Using modules with return value reuse. Common Modules Reusing Return Values ​​1c 8.3

This article provides a brief overview and specifics of functionality such as Reusing the Return Values ​​of Shared Modules.

Problems when working with 1C

Often, when working with the 1C program, it is required to obtain the values ​​stored in the database, they do not change for years. An example would be the value of constants. This group of values ​​can conditionally include the search for one of the elements of the directory or the search for the node of the exchange plan using the code, as well as the need to get the value of the details of the objects.

Such problems are solved quickly and simply using the following types of structures:

If DocumentDate > Constants.Regulation1137StartDate.Get() Then

But each time this code is executed, the database is accessed.

Many programmers use the following method to unload a database. They perform just one request to the knowledge base and cache the data that they may need. However, this method does not unload the databases to the desired value. The reasons for this may be as follows:

· not quite clear cycle of code execution (for example, during group reposting of documents);

Obtaining a strict set of data that is not needed at the moment is sometimes impossible or difficult;

· use of already cached data in various forms/calls.

Return Value Reuse Module

To solve the problems described above, the use of models with the reuse of return values ​​will help. What it is? This is a common client or server module, in which the "Per call" or "Per session" function should be set to Reuse return values. All operations and functions directly in the module are described as before.

The undoubted advantage of this method is that the return of the cached value occurs without actually executing the function code. This happens with all subsequent calls to the export functions of these modules. The same effect can be seen when measuring performance.

When the code is executed, the returned values ​​are cached through the values ​​of the passed parameters. So this happens directly when the code is executed

Node1 = OurModule.GetExchangeNodeWithAccounting("0001");

Node2 = OurModule.GetExchangeNodeWithAccounting("0002");

Both one and the other call lead to the execution of the corresponding operation and return different references. However, the nodes with the code 0001 or 0002 will be returned already during the next calls, without causing a repeated operation and, accordingly, without accessing the database.

The values ​​will be cached in isolation on each session, both on the client and on the server (depending on whether the call was made from the client or server module). Everything will work flawlessly if there are any peculiarities in the access rights settings or any other dependency of the received value.

A few BUT

As with any rule, there are exceptions to this method. Complex types should not be specified in function parameters, rather simple types such as Date, Number, Undefined, and so on. You should not try to specify as parameters, for example, a structure, an object, or a table of values. You will get the result the first time, but nothing sensible will come out the second time.

The return value can be of any type.

In addition, do not forget to pay attention to the size of the data you are caching, since the server memory, although huge, is not unlimited.

Feature or bug from 1C

Values ​​that are reused have an interesting feature. We can assume that this is a feature or a bug, but in any case, it is worth paying attention to.

When you enter the following code:

ValueStructure1 = OurModule.GetAttributesValuesStructure(ObjectReference);
ValueStructure1.Name = "New name";
ValueStructure2 = OurModule.GetAttributesValuesStructure(ObjectReference);

in ValueStructure2.Name, exactly the New name will appear. This can be used to update values ​​that have actually changed in the database, but it is not known how much longer this can be done. Because when creating standard solutions you can't do that.

If the cached data has been changed

If cached values ​​have changed in the database, there is only one way to use it - the UpdateReusedValues ​​method. In this case, the values ​​of the settings of all functions are reset in all modules. There is no possibility of updating by some parameter values, either functions or modules.

How a request is made in a loop

If you don't want to use a function that reuses return values, here are a few more creative ways to solve the problem.

· Universal procedures that return the details of arbitrary links.

· Creation of procedures that return values ​​of constants by their name. By the way, such procedures are in standard versions.

· Return a volume slightly larger than needed to reduce the number of calls. For example, if you need to get the rate of several currencies at the same time, it is desirable to call the function exclusively by date without selecting currencies. Having received all the rates, determine which currency is now needed and which is not.

· Creation of a procedure that will execute a query with simultaneous caching of the result obtained (incoming parameters - query text, several parameter names and values).

There is one more method I would like to talk about in more detail. This method is based on using a function that contains a call to the database, with the return value being reused directly in the loop, that is, a kind of query in the loop. In some cases, this construction can improve performance. The following condition must be met: there must be a small number different meanings input parameters encountered in the loop, and most of the combinations have already been received at least once earlier in this session. It should be remembered that it is extremely difficult to get a certain set of combinations of all input parameter values ​​in advance, and trying to get values ​​for all possible combinations can lead to reading too much data from the database.

We have given you only exemplary functions and methods. Therefore, before using them, evaluate the conditions in which your code will work.


General modules 1C- an object of configuration metadata 1C 8.3 and 8.2, which stores the program code that is often called in the configuration. A function/procedure can be called from anywhere in the configuration (if it is exported).

How to use the shared module

It is good practice to put a procedure or function in a common module if it is called in more than one place. First, if a procedure is corrected, it only needs to be corrected in one place. Secondly, it achieves greater order in the code.

A typical example of a common module is the processing of posting according to some register, getting the amount of the difference in working days, converting exchange rates, recalculating the quantity/price/amount in the tabular section, and other functions.

General Module Properties

One of the main differences between shared modules and other modules is that you cannot declare shared variables.

Get 267 1C video lessons for free:

Let's take a closer look at the properties palette of the common module:

  • Global- if the flag is set, functions and procedures from this module become available in the global context. Those. they can be called anywhere in the configuration without the name of the common module. However, a condition is added - the names of procedures and functions in this common module must be unique within the global context.
  • Server- The procedures and functions of this common module can be executed on the server.
  • Outer join- the program codes of this common module can be executed when connected by an external source (for example, COM).
  • Client (managed application)— Procedures and functions of this common module can be used in a thick client in managed application mode.
  • Client (regular application)— the program codes of this common module can be used in the thick client in the normal application mode.
  • Server call- a flag that allows the client to use the procedures and functions from this common module.
  • - if set to True, access rights checking will be disabled in this common module.
  • Reuse— defines the settings for returned values, if the option is enabled, then after the first execution the system will remember the value for these input parameters and will return already finished value. It can take the following values: not used- shutdown, at the time of the call- for the duration of a certain procedure, during the session- until the user has closed the session (program).

If you are starting to learn 1C programming, we recommend our free course (do not forget

/
Client-server interaction and security issues

Using Modules with Return Value Reuse

Scope: managed application, mobile app, common application.

1. Common modules with return values ​​reuse (hereinafter: cache) are provided for caching the results of the work of the functions that are placed in them - for the duration of the session or for the duration of the call. They should be used to save server computing resources and to minimize client-server interaction.

See also: "Reusing return values" section of the documentation for the 1C:Enterprise platform,
Using values ​​that affect client application behavior

2. At the same time, excessive (unjustified) use of common modules with reuse of return values ​​can lead to excessive memory consumption.

2.1. You MUST NOT create shared reusable modules that return data that is faster to evaluate than getting from the cache. For example, string constants. Besides the fact that getting a string constant each time will work much faster than getting it from a shared module with reuse, this data will take up cache memory.
For example, it is wrong to place in a reusable module:

It makes sense to cache data retrieved from the database, external sources data or by complex (resource-intensive) calculations. Moreover, in some cases, even the values ​​obtained from the database should not be cached if the benefit from caching them is not obvious. For example, you shouldn't cache constants (metadata object) of primitive types, as they often contribute only a small fraction of the total execution time of a resource-intensive operation.

2.2. You should only cache data that will be accessed frequently.

In particular, keep in mind that the cache does not store data forever. A cached value will be evicted from the cache 20 minutes after being computed or 6 minutes after it was last used (whichever comes first*). In addition, the value will be deleted if there is not enough random access memory in a server worker process, when a worker process is restarted, and when a client switches to a different worker process. Therefore, if no one "had time" to use the data from the cache, then this resource was wasted.

* Note: specific figures may vary depending on the version of the 1C:Enterprise platform used.

2.3. The range of values ​​for the input parameters of functions placed in shared reusable modules should not be wide.
For example, the configuration provides a function that receives a counterparty as input. If there are a lot of counterparties in the database, and the user scenario is such that the probability that someone will contact the same counterparty in 5 minutes is very low, then resources will be wasted. In addition, if this “waste” is multiplied by the number of concurrent users, then the waste of resources becomes significant.

3. You should not change the data obtained from the cache. Otherwise, there may be hidden errors in the operation of the program, as well as useless waste of memory (cache resources). Therefore, it is recommended to use values ​​whose state cannot be changed as return values, for example: FixedArray, FixedStructure.

This limitation is caused by the fact that the cache returns each time not a copy of the object, but a reference to the same object in memory. For example, if a new value is added to the array returned by a reusable function with each call when posting documents, then as a result the cache will “swell” very quickly. In addition, the next time you flush the cache, the added values ​​will be lost and the code that relied on them will not work correctly.

4. If a reusable module contains several export functions that are not only called “outside”, but also call each other, then you should keep in mind that the result of “internal” calls is not cached.
For example, if the module Data ExchangeRetryUse placed two export functions:

Function AutonomousSupported() Export Return . . . EndFunction Function ThisOfflineWorkplace() Export Return OfflineWorkSupported() AND . . . ; EndFunctions

which are called sequentially from the application code,

ExchangeDataReuseOfflineWorkSupported(); ... = ExchangeDataRetryThisOfflineWorkstation();

then the function Offline WorkSupported will be calculated twice.

The article continues the cycle "First steps in development on 1C", it discusses in detail the following issues:

  • What is a software module and what sections does it consist of?
  • What is the application module for? Why are there two? When does it start? What are the details of the work?
  • What events are associated with the start of the system, how and where to process them?
  • What is the external connection module for? When and how to use it?
  • When is the session module used?
  • What are shared modules? What are its properties and rules of operation? Why use the Reuse Return Values ​​property?
  • When is the form module used and what events can be handled in it?
  • What is the object module for? What sections does it consist of? How to view available module events?
  • What are the subtleties of working with value manager modules (for constants) and recordset modules (for registers)?
  • What is the difference between an object module and a manager module? When should you use the latter?

Applicability

The article deals with the 1C:Enterprise platform 8.3.4.496. The material is also relevant for current platform releases.

Modules in 1C:Enterprise 8.3

Modules are those objects that contain program code.

The Platform has enough a large number of types of modules, each of which has its own purpose and features.

Any line of code must be in a module. There are general purpose modules and object modules. Some modules can be compiled both on the Client and on the Server, and some only on the Server.

A module can consist of several sections. The variable declaration section describes the local variables of this module, which can later be used in any procedure.

Within each procedure, you can access the module variable. In addition, within the procedure itself, there may be another declaration of a variable with the same name. This will be a local variable for this procedure.

Despite the same name, these are two different variables: one is used inside a particular procedure, and the other is used outside it.

In some modules, the variables can be set to the compilation location (availability) on the Server or on the Client. For example:

The variable declaration section is followed by the procedures and functions section, which specifies the local methods of the module. Some modules require you to specify where the procedure or function will be compiled.

In principle, the compilation directive can be omitted. In this case, the default compilation directive is Server. However, for the convenience of analyzing the program code, it is recommended to explicitly indicate where this procedure will be compiled. The order in which the procedures are described does not matter.

At the end of the module, after the description of all procedures and functions, there is a section of the main program, which may contain some operators, initialize the local variables of the form module. This section is executed when the module is accessed.

So, for example, when opening the form of an element, the section of the main program of the form module is executed first of all.

It should be noted that the variable declaration section and the main program section do not exist for all modules (i.e., these sections are invalid in some modules). A procedure and function description section can exist in absolutely any module.

Application module

This module is designed to handle application startup and shutdown events. For example, when you start the application, you can download exchange rates from the Internet. At the end of the application, you can make sure the user about his intentions to end the work.

Also in the application module, there are special handlers that allow you to intercept external events from the equipment.

These can be events from a magnetic card reader, fiscal registrar. And these events can be handled in some way too.

It should be noted that it is the interactive launch of the system that is tracked in the application module.

The application module will not work if the 1C program is launched, for example, in com-connection mode. In this case, the program window is not created.

It should be noted that in Platform 8.3 there are two different application modules: the Managed Application module and the Regular Application module. Managed application module events are fired when the Thin and Thick Clients of the Managed Application and the Web Client are launched.

Module General application works when the Thick Client is started in the mode General application, which has the usual command interface in the form main menu.

If the application is running and Managed, and in the mode General application, then it is necessary to describe the handler procedures as for the module managed application, and for the module General application.

Module managed application can be selected from the context menu of the configuration root node.

This module can also be opened from the properties palette of the root configuration element.

To open a module General application, you should refer to the configuration settings (command Options on the menu Service).

A form will open Options. Bookmark General config edit mode must be specified Managed Application and General Application.

In this case, the module General application can also be opened from the properties of the root node.

List of events that can be processed for Managed and General application the same.

In this module, you can place a variable declaration section, a section for describing arbitrary procedures and functions, and a section for the main program. But in addition to arbitrary procedures and functions, special event handlers can be located in the module.

The list of available handlers can be viewed by calling the list of procedures and functions of the current module while the module is open.

The opened Procedures and functions window displays all procedures and functions of this module, as well as events for which handlers have not yet been created.

There are two events associated with the start of the system (“before” and “at”). Two events related to system shutdown (“before” and “at”). As well as processing an external event (for example, an event of a shop equipment).

When the "before" event handler is executed, it is considered that the action has not yet taken place. When the “on” event handler is executed, the action has already taken place.

Event BeforeStartingSystem occurs at the moment when Enterprise 8.3 is launched, but the application itself has not yet appeared on the screen. This event has such a parameter as Refusal.

If this parameter is set to True, then the application will not start. Event When Starting the System assumes that the action has already been taken, the window has already been created, and in this case we can, for example, display some special form. You can no longer refuse to launch.

Similarly, before shutting down the system, the application is still open and you can choose not to shut it down. When the system was shut down, the application window was already closed. It is only possible to perform additional actions, such as deleting some files or sending an email.

In the module managed application directives for compiling procedures and functions are not specified, since the module is compiled entirely on the Client side. This means that in the procedures and functions of the module, we will not be able to directly access, for example, reference books.

If from the module managed application you need to make a Server call, then for this you will need to create special with a flag displayed .

In the module General application there are no such restrictions, since this module will be compiled when loading the Thick Client. Almost all data types are available in the Thick Client.

Procedures, functions and variables of an application module can be described as export.

Since the module is compiled entirely on the Client, this means that in client procedures we can access this method and this property.

For example, from the form module of some object, you can call a procedure or function of the application module. However, it is recommended to use General Modules to describe general algorithms. The main purpose of the application module is to handle the start point and end point.

By analogy with the application module, this module is designed to handle the program opening event and the shutdown event.

Unlike the application module, which is initiated when the application is launched interactively, the external connection module operates in com-connection mode, i.e. when a 1C:Enterprise 8 object is created and a connection is made to a specific database.

This module has events: When Starting the System and when shutting down the system.

The outer connection module can be opened using either the context menu at the level of the root configuration object or the properties palette for the root node.

The outer join process itself is a process of programmatic work with information base, not interactive. Accordingly, at this moment it is impossible to use dialog forms, display warning messages, since there is no user interface.

In the External Connection Module, it is possible to describe export variables and export methods that will be available on the side where the external call to 1C:Enterprise 8.3 occurs.

Since there is no user interface in an outer connection, the Outer Connection Module is compiled entirely on the Server.

session module

This module is needed in order to initialize session parameters. Session parameters are fast global variables whose values ​​are available anywhere in the configuration.

You can open the Session Module either through the context menu or through the properties palette of the root node.

An event is provided in the Session Module SettingSessionParameters.

When the application starts, this procedure is called the very first. Session parameters are needed for any application operation: both when launched interactively and when launched in external connection mode.

The Session Module describes various actions to initialize session parameters depending on different conditions.

This module, as a rule, describes several procedures that are called from the procedure SettingSessionParameters. Therefore, all these procedures are separated into a separate module.

The session module always runs in privileged mode. This means that no permission check will be performed when accessing the database. The session module is compiled on the Server, i.e. it is possible to call any server methods (including reading values ​​from the database).

It is possible to define only procedures and functions in the Session Module, i.e. there is no variable declaration section and no main program section. You cannot declare export methods in a Session Module.

If at system startup it is necessary to perform some actions on the Server, for example, to create an element of some directory, then, as an option, it is possible to use the Session Module, because it is compiled on the Server and is always reliably executed at system startup. However, the following points must be taken into account:

  • procedure SettingSessionParameters is executed not only at system startup, but also when accessing uninitialized session parameters. Those. the SetSessionParameters handler can be called multiple times during application execution;
  • if the number of elements in the array of session parameters is equal to zero (the array of required parameters has the data type Undefined), then this is the moment the application is launched;
  • since the Session Module works in privileged mode and there will be no access checks, you should be very careful when working with database objects, since the user can gain access to data that should not be provided to him;
  • when the system starts, it is not yet known for certain whether the application will be launched. In this case, extra actions can be performed in the event handler of the SetSessionParameters event.

These modules are descriptions of some general algorithms, i.e. procedures and functions that can be called from various places.

Logically related methods can be grouped into different Common Modules. These modules are created inside the General branch.

You can add any number of shared modules. To make Common Module methods available elsewhere in the configuration, they must be defined with keyword Export. Client procedures of common modules will be available on the Client, and server procedures - on the Server.

In Common modules, only the section describing procedures and functions is available. Those. in a Common module you cannot declare variables and you cannot describe a section of the main program.

If a global variable is needed, either session parameters or application module export variables can be used.

For Common modules, you can set some parameters that will affect the behavior of this module. If the Global property is set for a Common module, then the export methods declared in this module will be available from outside directly, without any additional instructions.

Those. the General module will participate in the formation of the global configuration context.

Property Global for common modules can be useful. However, you should not use it universally for all common modules.

Those , which are marked with Global, will be compiled at system startup. The more such modules, the slower the program will start.

If the flag Global for General module is not specified, then the compilation of this module will be performed at the time of the first call to it (that is, after the system starts).

In addition, the use of global shared modules affects the understanding of the code. Calling methods of a non-global shared module is done through the name General module and the name of the method, for example:
Cost Calculation Module. Allocate Indirect Costs();

At the same time, the names of the General modules should reflect the content of the procedures described in them. Specifying the name of the Common Module when calling a procedure makes the code easier to understand.

For General module in Properties Palette property can be set Privileged.

Access rights are not controlled in a privileged module. This is necessary if in General module it is required to perform bulk data processing, obtaining data from the database.

Access control increases database access time, and bulk algorithms often need to run as fast as possible.

For example, a resource-intensive operation is the calculation wages. It needs to be done as quickly as possible. To do this, algorithms that calculate wages are placed in privileged .

At the same time, all procedures that ensure the completion of payroll documents are outside these Common modules. It is in these procedures that access control is performed.

In this way, a significant increase in performance can be achieved. This is especially true for the case of using the mechanism of line-by-line access differentiation to table records.

If the Common module is privileged, then the procedures of this module can only be compiled on the Server.

There are situations when some object should be inaccessible to the user, for example, a certain directory. But when carrying out any one document, an appeal to this handbook necessary.

Those. there is a need to temporarily expand the user's rights, and then return them to their original state. This effect can be obtained by using privileged Common modules.

To do this, in a privileged General module it is necessary to issue a procedure that accesses the necessary data.

This procedure will be called from the corresponding document. Those. the user is actually granted extended rights at the time this procedure is called.

For Common modules it is possible to specify the compilation location. Flags are used to determine whether the Common module will be available on the Client (managed application), on the Server, in the External connection mode.

In addition, if you switch the configuration editing mode to a Managed application and a regular application, then one more compilation context will be possible - the Client (normal application).

Thus, there are four options for the functioning of the program. Depending on the running application, depending on the work on the Client or on the Server, certain Common modules will be available or unavailable.

In addition to the ability to specify compilation flags, it is possible to specify compilation directives for procedures and functions located in the Common module.

If a compilation directive is specified for a method, then although the Generic module is available in all specified contexts, the accessibility of a particular method will be limited by the compilation directive.

In this case, the procedure cannot be accessed in a context that is not available in general for the entire module.

If the compilation directive is not specified for a procedure (function), then it will be compiled in all contexts defined for the module.

Those. in effect, multiple copies of the procedure will be made. The choice of a particular compiled instance depends on where the procedure is called (by the rule of closest call). At the same time, it should be taken into account that the code of such a procedure must be written taking into account its accessibility in all contexts defined for the module.

Common modules that are available in several different contexts at the same time are primarily designed to create procedures that are available in several contexts.

When creating a Generic module, it's good practice not to specify compilation directives. Those. the accessibility of procedures and functions should be determined by the properties of the module itself.

With this approach, client procedures will be located in separate Common Modules, and server procedures will be located in separate Common Modules.

Modules that have multiple compilation flags set are rarely used in practice. These are some common actions available on both the Client and the Server. Usually, these are some simple calculations.

Important! It is possible to access the export server methods of the Shared Module from the Client, but only if this Shared Module is compiled only on the Server. At the same time, a special checkbox is intended to provide access from the Client. .

For non-global Common modules, it is possible to cache those values ​​returned by functions. Those. the system can remember the result of its execution after the first call to the function. If this function is called again with the same parameters, the system will return the value already from the cache.

The purpose of this mechanism is to speed up repeated calls. To configure this behavior, you need to Properties Palette module to set the appropriate value for the Reuse return values ​​property.

By default, this property is set to Do not use. Other possible values: cache At the time of the call, or For the duration of the session.

This property makes sense to use only for those functions, the result of which depends solely on the input parameters. This mechanism is only available for non-global Common modules.

If the value of the corresponding parameter For the duration of the call is selected, then the cache will be active as long as the procedure from which the method of the Common module was called is running. If the value is For the duration of the session, then the cache is conditionally considered to be active while the user is working.

However, there are certain time limits. The cache is cleared automatically 20 minutes after the value is cached.

Form module

This module is designed to process user actions. For example, describe the program's reaction algorithm when a button is pressed. Or, for example, at the time of entering the value in the field, immediately check for correctness.

In addition to events associated with form controls (buttons, input fields), there are events associated directly with the form itself.

For example, you can handle the form open event and do some initial initialization. You can also handle the form close event and check if the user entered everything correctly.

There are forms managed and forms usual. The form data modules differ primarily in that the managed form module is clearly separated into a context. Each procedure (function) must have a compilation directive. In its normal form, all code is used on the Client.

In a managed form module, you can declare procedures and functions, you can declare variables, and you can describe a section of the main program.

The program code of the main program will be executed at the moment the form is initialized, i.e. when the user opens it. The figure shows a list of standard events for a managed form.

The list of managed form events is also visible in the property list for the form itself. This list is called in the managed form editor.

AT managed form you can handle the write event of the element. This event is present only for forms of objects (reference books, documents, and some others). If the form is not bound to a specific object, then there is no write event.

For a regular form module, the list of standard events is somewhat smaller, because in a managed form, many events are made in pairs (one is executed on the Client and the other on the Server). In the usual form, all code is executed on the Client.

Object module

These modules are typical for directories, documents, plans of types of calculations, charts of accounts and many other objects. The object module is designed to handle standard events. For example, an event for entering a directory element, an event for writing an element, deleting, posting a document, etc.

In principle, the write event also exists in the Form Module. But the write event in the Form Module occurs during interactive writing, when working with a specific form.

The write event in the Object Module will be fired on any write from any form of the given object. Also, if the object is written programmatically, the object's module event will fire in that case.

In the write event of the Object Module, you can embed all checks for the correctness of the data being written, since this procedure will work out at the time of absolutely any write.

The module of this object can be called via the context menu, from the object's Properties Palette, and from the object editing window.

The figure below shows a list of available events of the directory module.

In the Object Module, you can place a variable declaration section, describe arbitrary functions that may or may not be associated with an event, as well as a section of the main program.

In the main program section, you can, for example, initialize the local variables of this module. This program code will be executed when this Object Module is accessed.

It should be noted that all procedures of the Object Module are compiled on the Server. Accordingly, compilation directives are not required for procedures and functions of the Object Module. Some configuration objects do not have Object Modules.

This is due to the features of the objects themselves. Such objects include Constants and Registers. For Constant there is no object module, but there is a very similar module called Value manager module.

AT Value manager module you can handle recording events Constants and filling check processing.

The entire module context is executed on the Server.

For registers, there is a Recordset Module.

This module also has the ability to handle write events and perform a population check.

In Object Modules, Value Manager Modules (for constants), and Recordset Modules (for registers), you can describe methods that can be made exportable, and these methods will be available from outside.

Those. In addition to using the fixed methods of an object class, you can create additional methods for an object in the Object Module. This module should describe the relevant procedure with the keyword Export.

Then it will be possible to refer to this procedure from outside. And this method will be displayed in the context tooltip. New methods in the context tooltip are highlighted in blue (blue icon p() for procedures and f() for functions).

Similarly, you can create a new property by declaring a variable with the keyword Export. This property can also be accessed from outside.

Thus, it is possible to extend the functionality of objects (add new methods and new properties). The properties are dynamic and are not stored in the database.

If you need to use a property for an object that will be stored in the database, you should create an object attribute.

Manager module

This module exists for many objects (directories, documents, registers, etc.). The module is opened either through the context menu for the object, or through Properties Palette, or through the edit window.

In the Manager Module, you can override some standard events. For example, in ProcessingReceivingDataChoice, when an element is selected from the dictionary, you can do some additional filtering or checking.

In addition, you can create additional methods in the Manager Module and specify that they are export methods. In this case, it is possible to access these methods from outside.

In order to perform this call, you need to get the data type DirectoryManager.

The difference between the export methods of the Manager Module and the Object Module is that in order to call the method of the Object Module, you first need to get the object itself (that is, somehow get a link and then convert this link into an object).

After that, the export variables and methods of the Object Module will be available. For the Manager Module, the call is simpler, for example:
Directories.Accounts.MethodName

These are two different appeals. Convert from reference to object (method GetObject) is a fairly serious action for the system, since when an object is received, absolutely all the data of this object is read, which can be quite lengthy.

The second difference is that ObjectModule invoked in the context of a particular element. Accordingly, we can assume that it is applicable for this element (in most cases, this is the logic laid down).

As for the Manager Module, it describes some general action for a group or for all elements of a directory or some document. For example, if you need to print a reference item, you can use the Object Module.

But in the Manager Module it is possible to make a more universal mechanism that will print, among other things, a group of elements.

In addition, accessing the object's Module is still a longer action. Therefore, it is more preferable to solve this problem in the manager module.

This concludes our acquaintance with the modules in the configuration of the 1C:Enterprise system. If let down short summary all of the above, the bottom line is the following conclusions:

  • A software module is a part of the configuration that can only contain text in the built-in 1C language
  • Program modules are classified according to the types that we examined in this article. Each view is defined by its placement and available programming context.
  • The structure of the module consists of some sections, which are arranged in a certain sequence. The composition of sections is determined by the type of module.

Also note that we deliberately omitted one kind of module, namely the command module. It does not represent anything remarkable, and we suggest that you familiarize yourself with its functionality.

So far, we have considered all our program code fragmentarily from the applied solution, and, as a rule, we wrote it in some kind of small test configuration of our own. Are you aware that “you can’t just take it” and start editing the code of a typical configuration? Not? Then in the next article we will explain it all!

Often we have to get values ​​during the execution of the program that are stored in the database and do not change for years. A striking example is the values ​​of constants. In part, one can also include here the search for an element of the directory or the node of the exchange plan by code, obtaining the values ​​of the details of objects by reference.

Without thinking, "on the fly" such tasks are solved by constructions of the form:

If DocumentDate > Constants.Regulation1137StartDate.Get() Then

As a result, every time this code is executed, the database is "twitched".

Programmers who are more sensitive to their code perform one query to the database, caching all the data they need, but this approach does not always lead to the desired database unloading:

  1. The code execution loop can be implicit (for example, group reposting of documents)
  2. Obtaining a strict set of data (no more and no less) that will be required later is sometimes difficult or even impossible.
  3. Cached values ​​need to be used in different calls/forms

Return Value Reuse Module

To solve the described problems, the platform has modules with reuse of returned values. In fact, this is a normal generic module (client or server) with Return Value Reuse set to "Per Call" or "Per Session". In the module itself, procedures and functions are described as usual.

The whole point is that with multiple calls to the export functions of such modules - the first time the call is actually made as we expect, and all subsequent calls result in the return of the cached value without actually executing the function code. This effect can be observed in performance measurements.

The returned values ​​are, of course, cached in terms of the values ​​of the passed parameters, i.e. when executing code

Node1 = OurModule.GetExchangeNodeWithAccounting("0001"); Node2 = OurModule.GetExchangeNodeWithAccounting("0002");

Both calls will indeed lead to the execution of the corresponding procedure and return different references, and subsequent attempts to get the node with the code 0001 or 0002 will return the corresponding nodes without calling the procedure and, as a result, the database.

Values ​​are cached separately for each session on the client or server (depending on whether the client or server module). Those. if there are features of setting access rights or other dependence of the received value on the current user, everything will work correctly.

What Not to Do

There is one limitation. You can only use functions as parameters. simple types. Undefined, Null, Boolean, Date, String, Number, Reference. No structures, value tables, objects, etc. If you try to pass, for example, a structure as a parameter, everything will work, but you can forget about reusing the received value.

The return value can be of any type.

Also, you should pay attention to the size of the data that you cache. You are unlikely to fill all the server memory, but remember that resources are not infinite.

Bug or feature from 1C

Reusable values ​​have an interesting property. Whether this is a bug or a feature is not clear, but it does not hurt to know about it. If you run the following code:

ValueStructure1 = OurModule.GetAttributesValuesStructure(ObjectReference); ValueStructure1.Name = "New name"; ValueStructure2 = OurModule.GetAttributesValuesStructure(ObjectReference);

Then in ValueStructure2.Name it will be exactly "New name". In principle, this can be used to update the values ​​actually changed in the database, but it is not clear when they will close and whether the shop will be closed. When developing standard solutions, this is prohibited.

What to do when changing cached data

There is only one "legitimate" method to handle a change in a cached value in the database. This is the UpdateReusedValues() method. The values ​​of all functions for all parameters of all modules will be reset. You cannot update for specific parameter values ​​/ functions / modules.

Accordingly, due to such a voluntaristic approach, it is necessary to use this function very carefully: after using it, the entire system will work much more slowly for some time.

Encroaching on the sacred: writing a query in a loop

In addition to the obvious options for using functions with return value reuse, there are many interesting, universal, non-standard approaches, including:

  • Writing universal procedures that return the details of arbitrary links (available in the BSP)
  • Writing procedures that return the values ​​of constants by the name of the constant (there are in most typical ones)
  • Returning a "slightly larger" amount of data than necessary in order to reduce the number of calls (for example, if you need to get the rates of several currencies at once, it makes sense to call the function by date without selecting the currency, get the rates of all currencies and then "figure out on the spot" which of the currencies in currently needed)
  • Writing a procedure that executes a query with result caching (the input parameters will be the query text and a couple of parameter names and values)

But there is another approach that I want to dwell on in detail. This is the use of a function containing a database call, with the return value being reused in a loop. Those. in fact, this is a request in a cycle. In general, we were taught not to do this, but there are times when structuring the code this way will lead to better performance if:

  1. The number of different values ​​of the input parameters that will occur within the cycle is small and the vast majority of combinations with a high degree of probability were obtained earlier in this session.
  2. It is difficult to get a strict set of combinations of input parameter values ​​that will occur in the loop in advance, and obtaining values ​​for all possible combinations of input parameter values ​​will lead to reading a large amount of data from the database

As you can see, the wording is not precise and looks more like parting words than rules. Therefore, always keep the context in mind, evaluate the current picture, think about the conditions in which your code will work.