New releases "1C: Trade Management": update without development. Using external COM components (.dll) or any client methods in scheduled tasks of the server base

October 23 released a new configuration release "1C: Trade Management". Once again, the update included changes in VetIS, EGAIS, and the general functionality of the configuration was almost not affected.

What changed?

If you look at the structure of the changes that are included in the latest release of the configuration "1C: Trade Management", then more than half is an update by EGAIS, VetIS, and only a few lines in the description of the release are devoted to expanding the functionality of the software product, which are not caused by any legislative acts.

Sections in which changes occurred:

    in retail sales, support was added for reading a two-dimensional bar code of excise and federal special stamps of a new sample containing a digital identifier EGAIS;

    improved integration with the veterinary control system (VetIS);

    improved exchange with the EGAIS system;

    new features of the electronic document exchange service have been added;

    improvements were made regarding the 1C service: Business Network;

    improved integration with Yandex.Cash.

In terms of overall functionality, several changes have been made to the planning and treasury unit. And traditionally permanent additions to VAT accounting.

At the same time, the latest current configuration release "1C: Trade Management"   is no exception - now the development of the configuration for operational accounting is mainly on the way to closing tasks that arise as a result of legislative regulation in the field of trade. It is logical that support for regulatory requirements becomes more priority, and, ultimately, determines the direction of development of the software solution as a whole.

Is operational accounting becoming regulated?

Traditionally configuration "1C: Trade Management"   used to automate operational accounting. Moreover, in conjunction with "1C: Accounting"   it was customary to “unload” all requirements for modifying the standard functionality in "1C: UT",   to keep the possibility of updating the accounting program with minimal labor.

Considering the volume of regulatory documents for operational accounting in trade and the reflection of these requirements in a typical configuration, there are reasons to more carefully approach changes to the standard functionality of a trading configuration. For example, problems with the exchange with the Mercury system may, if not paralyze the activity of a number of enterprises, then lead to long downtimes, at least.

The use of the extension mechanism can be considered as one of the solution options, especially since 1C is actively involved in this functionality. Of course, this approach will require additional labor from the developers. But this is the best way to support changes in modern configurations.

More radical will be the distribution of functionality between a typical configuration "1C: Trade Management"   and some kind of external accounting or analytical systems. Here again, “1C” has done enough to effectively solve such problems at the platform level.

In any case, now when designing corporate accounting systems and distributing functionality between configurations, you need to keep in mind: it is possible that update "1C: Trade Management"   will have to if not as often as "1C: Accounting", then it’s definitely not 1-2 times a year, as so many have done before.

  • Tutorial

Introduction

  This article gives an idea of \u200b\u200bthe work of external components in the "1C: Enterprise" system.
  The process of developing an external component for the "1C: Enterprise" system version 8.2, running on a Windows operating system with a file version of the work, will be shown. This option is used in most solutions designed for small businesses. VK will be implemented in the C ++ programming language.

External components "1C: Enterprise"

  “1C: Enterprise” is an expandable system. To expand the functionality of the system, external components (VK) are used. From the developer's point of view, VC is an external object that has properties and methods, and can also generate events for processing by the 1C: Enterprise system.
  External components can be used to solve a class of tasks that are difficult or even impossible to implement using the programming language built into the "1C: Enterprise". In particular, tasks that require low-level interaction with the operating system, for example, to work with specific equipment, can be attributed to this class.
  The 1C: Enterprise system uses two technologies for creating external components:
  • using native API
  • using COM technology
  Given the restrictions between the two above technologies, the difference is insignificant, so we will consider the development of VK using the Native API. If necessary, the implemented developments can be applied for the development of VK using COM technology, and also, with minor modifications, are used for use in the 1C: Enterprise system with other work options other than the file operation mode.
VK structure
  The external component of the 1C: Enterprise system is presented in the form of a DLL library. The library code describes the IComponentBase descendant class. In the created class, the methods responsible for the implementation of the functions of the external component must be defined. Overrideable methods will be described in more detail later in the course of the presentation of the material.

Launch demo VK

A task:
  1. Build the external component supplied with the ITS subscription and intended to demonstrate the basic capabilities of the external component mechanism in 1C
  2. Connect the demo component to 1C configuration
  3. Ensure the correct functionality of the declared functions
Compilation
  The demo VK is located on the ITS subscription disk in the directory “/ VNCOMP82 / example / NativeAPI”.
  We will use Microsoft Visual Studio 2008 to build the demo VK. Other versions of this product do not support the Visual Studio project format used.


  Open the AddInNative project. In the project settings, we connect the directory with the header files needed to build the project. By default, they are located on the ITS drive in the directory / VNCOMP82 / include.
  The result of the assembly is a file /bind/AddInNative.dll. This is the compiled library for connecting to the 1C configuration.
VK connection to 1C configuration
  Create an empty 1C configuration.
  The following is the code for the managed application module.
  Pere DemoKomp; System Startup Procedure () Connect an ExternalComponent ("... \\ bind \\ AddInNative.dll", "DemoVK", ExternalComponent.Native Type); DemoComp \u003d New ("AddIn.DemoVK.AddInNativeExtension"); EndProcedures
  If an error was not reported when starting the 1C configuration, then the VK was successfully connected.
  As a result of the above code, an object appears in the global visibility of the configuration. DemoComphaving properties and methods that are defined in the code of the external component.
Demonstration of the embedded functionality
Check the performance of the demo VK. To do this, try to set and read some properties, call some VK methods, and also receive and process the VK message.
  In the documentation supplied on the ITS disk, the following functionality of the demo VK is stated:
  1. Controlling the state of a component object
      Methods: Enable, Switch off
      Properties: Included
  2. Timer control
      Every second, the component sends a message to the 1C: Enterprise system with the parameters Component, Timer   and the line counter of the system clock.
      Methods: StartTimer, Stop Timer
      Properties: There is a timer
  3. Method ShowInStrokeStatus, which displays in the status bar the text passed to the method as parameters
  4. Method DownloadPicture. Loads an image from the specified file and transfers it to the 1C: Enterprise system in the form of binary data.
  We will verify the operability of these functions. To do this, execute the following code:
  Pere DemoKomp; System Startup Procedure () Connect an ExternalComponent (...); DemoComp \u003d New ("AddIn.DemoVK.AddInNativeExtension"); DemoComp. Turn off (); Report (DemoComp. Enabled); DemoComp Enable (); Report (DemoComp. Enabled); DemoComp. StartTimer (); End of Procedures Procedure for Processing an External Event (Source, Event, Data) Report (Source + "" + Event + "" + Data); EndProcedures
  The result of starting the configuration is shown in the image


  The "Messages" panel displays the results of method calls DemoCom Disable ()   and Demo Comp. Enable (). The subsequent lines in the same panel contain the results of processing received messages from VC - Source, Event   and Data   respectively.

Arbitrary name of the external component

Task: Change the name of the external component to any.
  The previous section used the identifier AddInNativeExtensionwhose meaning has not been clarified. In this case AddInNativeExtension   is the name of the extension.
  VC code defines a method RegisterExtensionAs, returning to the system "1C: Enterprise" the name that is necessary for subsequent registration of VK in the system. It is recommended to specify an identifier that to some extent reveals the essence of the external component.
  We give the full method code RegisterExtensionAs   with the changed extension name:
bool CAddInNative :: RegisterExtensionAs (WCHAR_T ** wsExtensionName) (wchar_t * wsExtension \u003d L "SomeName"; int iActualSize \u003d :: wcslen (wsExtension) + 1; WCHAR_T * dest \u003d 0; if (m_iMemory) (if (m_iMememory ((void **) wsExtensionName, iActualSize * sizeof (WCHAR_T))) :: convToShortWchar (wsExtensionName, wsExtension, iActualSize); return true;) return false;)
  In the above example, the name VK is changed to Somename. Then when connecting the VC, you must specify a new name:
  DemoComp \u003d New ("AddIn.DemoVK.SomeName");

Extension of the list of properties of VK

A task:
  1. Explore the implementation of VC properties
  2. Add a read-write string property
  3. Add a read-write property of the string type that stores the data type of the last property set. When setting a property value, no action is taken

  To determine the properties of the created component, the developer needs to implement the following methods in the code of the AddInNative.cpp library:
Getnprops
  Returns the number of properties of this extension, 0 - in the absence of properties
FindProp
  Returns the serial number of the property whose name is passed in the parameters
Getpropname
  Returns the name of the property by its serial number and by the transmitted language identifier
Getpropval
  Returns the value of the property with the specified serial number
Setpropval
  Sets the value of the property with the specified serial number
IsPropReadable
  Returns the flag the flag of the ability to read the property with the specified serial number
IsPropWritable
  Returns the flag the flag of the ability to write properties with the specified serial number


  Consider the implementation of the above class methods CAddInNative.
  The demo VK defines 2 properties: Included   and There is a timer (Isenabled   and IsTimerPresent).
  Two arrays are defined in the global scope of the library code:
  static wchar_t * g_PropNames \u003d (L "IsEnabled", L "IsTimerPresent"); static wchar_t * g_PropNamesRu \u003d (L "On", L "YesTimer");
  which store Russian and English property names. In the header file AddInNative.h   the enumeration is determined:
  enum Props (ePropIsEnabled \u003d 0, ePropIsTimerPresent, ePropLast // Always last);
ePropIsEnabled   and ePropIsTimerPresent, respectively, having values \u200b\u200b0 and 1 are used to replace serial numbers of properties with meaningful identifiers. An ePropLast with a value of 2 is used to get the number of properties (using the GetNProps method). These names are used only inside the component code and are not accessible from the outside.
FindProp and GetPropName methods search arrays g_PropNames   and g_PropNamesRu.
  To store the field values \u200b\u200bin the library module, the CAddInNative class defines properties that store the value of the component properties. Methods Getpropval   and Setpropval   respectively return and set the value of these properties.
  Methods IsPropReadable   and IsPropWritable   and return trure   or false, depending on the transferred serial number of the property in accordance with the application logic.
  In order to add an arbitrary property, you must:

  1. Add name of added property to arrays g_PropNames   and g_PropNamesRu   (file AddInNative.cpp)
  2. In the listing Props   (file AddInNative.h) front ePropLast   add a name that uniquely identifies the property being added
  3. Organize memory for storing property values \u200b\u200b(create component module fields storing corresponding values)
  4. Make changes to methods Getpropval   and Setpropval   to interact with the memory allocated in the previous step
  5. In accordance with the application logic, make changes to the methods IsPropReadable   and IsPropWritable
  Paragraphs 1, 2, 5 do not need to be clarified. Details of the implementation of these steps can be found by studying the appendix to the article.
  Let's name the test properties. Test   and Type Check   respectively. Then, as a result of paragraph 1, we have:
  static wchar_t * g_PropNames \u003d (L "IsEnabled", L "IsTimerPresent", L "Test", L "TestType"); static wchar_t * g_PropNamesRu \u003d (L "Enabled", L "YesTimer", L "Test", L "TypeTest");
  Listing Props   will look like:
  enum Props (ePropIsEnabled \u003d 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Always last);
  To significantly simplify the code, we will use STL C ++. In particular, for working with strings Wcharconnect the library wstring.
  To save the method value Test, define in the class CAddInNative   in scope private field:
  string test1;
  To transfer string parameters between 1C: Enterprise and the external components, the 1C: Enterprise memory manager is used. Consider his work in more detail. Functions are used to allocate and free memory. AllocMemory   and Freeememorydefined in the file ImemoryManager.h. If necessary, pass the string parameter to the 1C: Enterprise system, the external component must allocate memory for it under the function call AllocMemory. Her prototype is as follows:
  virtual bool ADDIN_API AllocMemory (void ** pMemory, unsigned long ulCountByte) \u003d 0;
  Where pMemory   - address of the pointer in which the address of the allocated memory will be placed,
ulCountByte   - the size of the allocated memory.
An example of allocating memory for a string:
  WCHAR_T * t1 \u003d NULL, * test \u003d L "TEST_STRING"; int iActualSize \u003d wcslen (test1) +1; m_iMemory-\u003e AllocMemory ((void **) & t1, iActualSize * sizeof (WCHAR_T)); :: convToShortWchar (& t1, test1, iActualSize);
  For the convenience of working with string data types, we describe the function wstring_to_p. It receives a wstring string as a parameter. The result of the function is a filled structure. tVariant. Function Code:
  bool CAddInNative :: wstring_to_p (std :: wstring str, tVariant * val) (char * t1; TV_VT (val) \u003d VTYPE_PWSTR; m_iMemory-\u003e AllocMemory ((void **) & t1, (str.length () + 1) * sizeof (WCHAR_T)); memcpy (t1, str.c_str (), (str.length () + 1) * sizeof (WCHAR_T)); val -\u003e pstrVal \u003d t1; val -\u003e strLen \u003d str.length (); return true;)
  Then the corresponding case section of the method switch statement Getpropval   will take the form:
  case ePropTest1: wstring_to_p (test1, pvarPropVal); break;
  Method Setpropval:
  case ePropTest1: if (TV_VT (varPropVal)! \u003d VTYPE_PWSTR) return false; test1 \u003d std :: wstring ((wchar_t *) (varPropVal -\u003e pstrVal)); break;
  To implement the second property, we define a class field CaddInnative
  uint8_t last_type;
  in which we will save the type of the last transmitted value. To do this, add the command to the CaddInNative :: SetPropVal method:
  last_type \u003d TV_VT (varPropVal);
  Now, when requesting to read the value of the second property, we will return the value last_typewhat the designated task requires.
  Check the operability of the changes made.
  To do this, we bring the appearance of the 1C configuration to the form:
  Pere DemoKomp; System Startup Procedure () Connect an ExternalComponent ("...", "DemoVK", ExternalComponent.Native Type); DemoComp \u003d New ("AddIn.DemoVK.SomeName"); DemoComp.Type Check \u003d 1; Report (String (DemoComp.TypeCheck)); DemoComp.Test \u003d "Vasya"; Report (String (DemoComp.Test)); DemoComp.Test \u003d "Petya"; Report (String (DemoComp.Test)); Report (String (DemoComp.TypeCheck)); EndProcedures
  As a result of the launch, we get the sequence of messages:
3
   Vasya
   Petya
22

The second and third messages are the result of reading the property set in the previous step. The first and second messages contain a code of the type of the last set property. 3 corresponds to an integer value, 22 to a string value. Matching types and their codes is set in the file types.hwhich is located on the ITS drive.

Extension of the list of methods

A task:
  1. Extend the functionality of the external component with the following functionality:
  2. Explore ways to implement external component methods
  3. Add Function Method Funkts1, which takes two lines as a parameter (“Parameter1” and “Parameter2”). As a result, a string of the form: “Check. Parameter1, Parameter2 »
  4. Make sure that the changes made are working.

  To determine the methods of the created component, the developer needs to implement the following methods in the code of the AddInNative library:
GetNMethods, FindMethod, GetMethodName
  Designed to obtain respectively the number of methods, search for the number and name of the method. Similar to corresponding methods for properties.
Getnparams
  Returns the number of method parameters with the specified serial number; if a method with this number is absent or has no parameters, returns 0
GetParamDefValue
  Returns the default value of the specified parameter of the specified method
HasRetVal
  Returns the flag of the presence of a method with the specified serial number of the return value: true for methods with a return value and false   otherwise
Callasproc
false, a runtime error occurs and the execution of the 1C: Enterprise module is terminated. Memory for an array of parameters is allocated and freed by 1C: Enterprise.
Callasfunc
  Executes a method with the specified sequence number. If the method returns false, a runtime error occurs and the execution of the 1C: Enterprise module is terminated. Memory for an array of parameters is allocated 1C: Enterprise. If the return value is of type string or binary data, the component allocates memory with a function AllocMemory   memory manager, writes data there and stores this address in the corresponding field of the structure. 1C: The enterprise will free this memory by calling Freeememory.
  A complete description of the methods, including a list of parameters, is described in detail in the documentation supplied on the ITS disk.
  Consider the implementation of the methods described above.
  In the component code, two arrays are defined:
  static wchar_t * g_MethodNames \u003d (L "Enable", L "Disable", L "ShowInStatusLine", L "StartTimer", L "StopTimer", L "LoadPicture"); static wchar_t * g_MethodNamesRu \u003d (L "Turn On", L "Turn Off", L "ShowInStrokeStatus", L "StartTimer", L "StopTimer", L "DownloadPicture");
  and listing:
  enum Methods (eMethEnable \u003d 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Always last);
  They are used in functions. GetNMethods, FindMethod   and GetMethodName, by analogy with the description of the properties.
  Methods Getnparams, GetParamDefValue, HasRetVal   implement switch, depending on the passed parameters and application logic, return the required value. Method HasRetVal in its code it has a list of only methods that can return a result. For them, he returns true. For all steel methods, returns false.
  Methods Callasproc   and Callasfunc   contain directly executable method code.
  To add a method that can only be called as a function, you need to make the following changes in the source code of the external component:
  1. Add method name to arrays g_MethodNames   and g_MethodNamesRu   (file AddInNative.cpp)
  2. Add a meaningful method identifier to the Methods enumeration (file AddInNative.h)
  3. Make a change to the function code Getnparams   in accordance with the program logic
  4. Modify the method code if necessary GetParamDefValueif you want to use the default values \u200b\u200bof the method parameters.
  5. Make changes to the function HasRetVal
  6. Make changes to the logic of the functions Callasproc   or Callasfuncby placing the directly executable method code there
  We will give arrays g_MethodNames   and g_MethodNamesRuas well as listing Methods   to view:
  static wchar_t * g_MethodNames \u003d (L "Enable", L "Disable", L "ShowInStatusLine", L "StartTimer", L "StopTimer", L "LoadPicture", L "Test"); static wchar_t * g_MethodNamesRu \u003d (L "Turn on", L "Turn off", L "ShowInStrokeStatus", L "StartTimer", L "StopTimer", L "DownloadPicture", L "Test");

Enum Methods (eMethEnable \u003d 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Always last);
  Edit the function Getnpropsso that it returns the number of parameters of the Test method:
  long CAddInNative :: GetNParams (const long lMethodNum) (switch (lMethodNum) (case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; default: return 0;) return 0;)
  Make changes to the function:
  bool CAddInNative :: GetParamDefValue (const long lMethodNum, const long lParamNum, tVariant * pvarParamDefValue) (TV_VT (pvarParamDefValue) \u003d VTYPE_EMPTY; switch (lMethodNum) (case eMethMethethablestable / There are no parameter values \u200b\u200bby default break; default: return false;) return false;)
  Thanks to the added line
  case eMethTest:
  in the absence of one or more arguments, the corresponding parameters will have an empty value ( VTYPE_EMPTY) If you need a default value for the parameter, you must specify it in the section eMethTest   function switch statement CAddInNative :: GetParamDefValue.
  Since the Test method can return a value, it is necessary to make changes to the function code HasRetVal:
bool CAddInNative :: HasRetVal (const long lMethodNum) (switch (lMethodNum) (case eMethLoadPicture: case eMethTest: return true; default: return false;) return false;)
  And add the executable method code to the function Callasfunc:
  bool CAddInNative :: CallAsFunc (const long lMethodNum, tVariant * pvarRetValue, tVariant * paParams, const long lSizeArray) (... std :: wstring s1, s2; switch (lMethodNum) (case eMethLoadPicture: ... break; case eMethest if (! lSizeArray ||! paParams) return false; s1 \u003d (paParams) -\u003e pwstrVal; s2 \u003d (paParams + 1) -\u003e pwstrVal; wstring_to_p (std :: wstring (s1 + s2), pvarRetValue); ret \u003d true ; break;) return ret;)
  Compile the component and bring the configuration code to the form:
  Pere DemoKomp; System Startup Procedure () Connect an ExternalComponent ("...", "DemoVK", ExternalComponent.Native Type); DemoComp \u003d New ("AddIn.DemoVK.SomeName"); lane \u003d DemoComp.Test ("Hello,", "Peace!"); Report (per); EndProcedures
  After starting the configuration, we will receive the message: “Hello World!”, Which indicates that the method worked successfully.

Timer

A task:
  1. Learn timer implementation in demo VK
  2. Modify the "StartTimer" method, adding the ability to pass in the parameters the interval of the timer (in milliseconds)
  3. Make sure that the changes made are working.

  In WinAPI, you can use the message to work with time WM_TIMER. This message will be sent to your program at the time interval that you set when creating the timer.
  To create a timer, use the function Settimer:
  UINT SetTimer (HWND hWnd, // window handle UINT nIDevent, // identifier (number) of the timer UINT nElapse, // delay TIMERPROC lpTimerFunc); // function pointer
  Operating system will send a message WM_TIMER   into the program with the interval specified in the argument nElapse   (in milliseconds). In the last parameter, you can specify the function that will be executed each time the timer is triggered. The title of this function should look like this (the name can be anything):
  void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  Consider a timer implementation in a demo VK.
  Since we are considering the process of developing an external component for an OS of the Windows family, we will not consider the implementation of the timer in other operating systems. For GNU / Linux, in particular, the implementation will differ in the syntax of the function Settimer   and Timerproc.
  In executable code, the method is called Settimerthat the function is passed to Mytimerproc:
m_uiTimer \u003d :: SetTimer (NULL, 0,100, (TIMERPROC) MyTimerProc);
  The identifier of the created timer is placed in a variable m_uiTimerso that later it can be turned off.
  Function Mytimerproc   as follows:
  VOID CALLBACK MyTimerProc (HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time) (if (! PAsyncEvent) return; wchar_t * who \u003d L "ComponentNative", * what \u003d L "Timer"; wchar_t * wstime \u003d new wchar_t; if (wstime) (wmemset (wstime, 0, TIME_LEN); :: _ ultow (dwTime, wstime, 10); pAsyncEvent-\u003e ExternalEvent (who , what, wstime); delete wstime;))
  The essence of the function is that the method is called ExternalEvent, which sends a message to the 1C: Enterprise system.
  To expand the functionality of the method StartTimer   we will perform the following actions:
  Modify the method code Getnparams   so that it is for the method eMethStartTimer   returned value 1:
  case eMethStartTimer: return 1;
  Here is the method code Callasproc   to view:
  case eMethStartTimer: if (! lSizeArray || TV_VT (paParams)! \u003d VTYPE_I4 || TV_I4 (paParams)<= 0) return false; pAsyncEvent = m_iConnect; #ifndef __linux__ m_uiTimer = ::SetTimer(NULL,0,TV_I4(paParams),(TIMERPROC)MyTimerProc); #else // код для GNU/Linux #endif break;
  Now check the performance. To do this, we will write the code in the module of the managed application for configuration:
  Pere DemoKomp; System Startup Procedure () Connect an ExternalComponent ("...", "DemoVK", ExternalComponent.Native Type); DemoComp \u003d New ("AddIn.DemoVK.SomeName"); DemoComp. StartTimer (2000); EndProcedures
  After starting the configuration, the program will receive messages with an interval of 2 seconds, which indicates the correct operation of the timer.

Interaction with the system "1C: Enterprise"

  For interaction between the external component and the 1C: Enterprise system, methods of the IAddInDefBase class described in the file are used AddInDefBase.h. We list the most commonly used:
  Error message generation
  virtual bool ADDIN_API AddError (unsigned short wcode, const WCHAR_T * source, const WCHAR_T * descr, long scode)
wcode, scode   - error codes (a list of error codes with a description can be found on the ITS disk)
source   - source of error
descr   - error description
  Sending a message to the 1C: Enterprise system
  virtual bool ADDIN_API ExternalEvent (WCHAR_T * wszSource, WCHAR_T * wszMessage, WCHAR_T * wszData) \u003d 0;
wszSource   - message source
wszMessage   - Message text
wszData   - transmitted data
  Message interception is performed by the External Event Processing procedure
  Registration of an external component in the 1C: Enterprise system
virtual bool ADDIN_API RegisterProfileAs (WCHAR_T * wszProfileName)
wszProfileName   is the name of the component.
  These methods are enough for the full interaction of VK and 1C. To receive data by the external component from the 1C: Enterprise system and vice versa, the external component sends a special message, which in turn is intercepted by the 1C system and, if necessary, calls the methods of the external component for data feedback.

TVariant data type

  When exchanging data between an external component and the 1C: Enterprise system, the tVariant data type is used. It is described in the types.h file, which can be found on the ITS disk:
  struct _tVariant (_ANONYMOUS_UNION union (int8_t i8Val; int16_t shortVal; int32_t lVal; int intVal; unsigned int uintVal; int64_t llVal; uint8_t ui8Val; uint16_t ushortVal; uint32_t ulVltlVlrtlVlrltrVlrtrVlrtrVlrtrVlrtlVlrtrVlrt bVal; char chVal; wchar_t wchVal; DATE date; ID IDal ; // count of bytes) __VARIANT_NAME_3 / * str * /; _ANONYMOUS_STRUCT struct (WCHAR_T * pwstrVal; uint32_t wstrLen; // count of symbol) __VARIANT_NAME_4 / * wstr * /;) __VARIANT_Nle_b_1le_b_name_1_bt_name_1_bt_name_1; dimensional array in pvarVal TYPEVAR vt;);
  A type tVariant   is a structure that includes:
  • mixture (union) intended directly for data storage
  • data type identifier
  In general, working with type variables tVariant   happens according to the following algorithm:
  1. Determining the type of data that is currently stored in a variable
  2. Access to the corresponding field of the mixture, for direct access to data
  Use type tVariant   significantly simplifies the interaction of the 1C: Enterprise system and the external component

application

  The examples directory contains examples for the article.
  examples / 1 - launch the demo component
  examples / 2 - demonstration of property list extension
  examples / 3 - demonstration of extension of the list of methods
  Each directory contains a VS 2008 project and a ready-made 1C configuration.

For example, you won’t be able to rewrite the component if you are not its author and there are simply no sources. Or if the simple types (number, string, boolean, date) that are not supported by the Native API technology for its operation are enough.

There are no special problems with the file base. The scheduled task is called in the background process of a regular user. Therefore, client calls are available to him. When starting a scheduled task in the server database, there is no client context, respectively, a call Connect External Component ()   not available.

In this case, you can call the component on the client.   To do this, it is enough to run from the scheduled task on the server the launch of another 1C session in which to perform the necessary actions on the client. Well, do not forget then to end the running session.

Suppose, in our routine, we are generating and saving a report that uses the external COM component NameDeclension.dll to declare the name. On a file base, such a scheduled task will work correctly; it will not work to connect to the server component.

To fix the problem, add a procedure to the module of scheduled tasks that in server mode will start another session and in it will execute a call from the external processing to generate a report on the client.

   # If the Client Then the Procedure Perform Formation and Saving the Report () Export If Connecting the External Component ("SharedMock.NAMEDECL", "Skl", Type of the ExternalComponent.COM) Then Component \u003d New ("AddIn.Сл.NameDeclension"); // Here is the code for generating and saving the report. Otherwise, the Log of the Registration Log ("Task Tasks", Log Level of the Log. Error, "Failed to connect the external component on the client"); End If; EndProcedures # Otherwise, the Procedure Run FormationSaveReport () Export ExecuteOperationOn the Client ("Job Settings. ExecuteFormationSaveReport ()"); EndProcedures Procedure Perform the Operation On the Client (Parameter For Execution) Export Username \u003d ""; User Password \u003d ""; Path to External Processing \u003d "c: /temp/Autostart.epf"; Quote \u003d "" ""; DirectoryBIN \u003d DirectoryPrograms (); ConfigurationK Path \u003d ConnectionBaseStringString (); ConfigurationK Path \u003d Page Replace (ConfigurationK Path, Quotation Mark, Quotation Mark + Quotation Mark); Start String \u003d Quotation Mark + Directory BIN + "1cv8.exe" + Quotation Mark + "ENTERPRISE" + "/ IBConnectionString" + Quotation Mark + ConfigurationK + Quotation Mark + "/ N" + Quotation Mark + Username + Quotation Mark + "/ P" + Quotation Mark + User Password + Quotation Mark + "/ Execute" + Quotation Mark + Path to External Processing + Quotation Mark + "/ C" + Quotation Mark + Parameter For Execution + Quotation Mark; Launch Application (Launch String); EndProcedures #EndIf

An external processing code that will simply cause the client to print the desired report from the scheduled tasks module and end the session after generating the report.

Attempt to Run (Startup Parameter); Exception End Attempts; Finish System Work (False);

The convenience of the solution is that when setting up scheduled tasks it does not matter in which mode the task will be launched. If the database is file, then the necessary procedure will start immediately. If the database is server and when starting the client context is missing, then a new session will be initialized and the procedure will work correctly in the client context.

Code for a regular application. Theoretically, it will work in a similar way in the managed one.

p.s.   Also, this approach can be used to perform any client procedures in scheduled tasks.

The mobile application allows you to carry out warehouse operations (inventory of goods and fixed assets, moving goods) in 1C Accounting 3. +. The application is developed natively on Android. For full-fledged work, when exchanging through a file, only external processing is required. This application does not need intermediate databases and any additional software. The application can work with a complete lack of communication.

Functionality:
  . Inventory of goods;
  . Inventory of fixed assets;
  . Moving goods;

Link to download.

Version history.

Support for Android versions.

Android 4.4 and higher.

Support for configurations.

1C: Accounting 3. +

Support for barcode scanners and TSD.

  • GS-M100BT is supported in SPP mode;
  • TSD CARIBE PL 50L
  • Any scanners in HID mode connected via OTG are supported.

Functional.

Inventory of goods.

To carry out an inventory of goods, it is necessary in 1C to prepare a document Inventory of goods without the actual quantity. Next, you need to go to the application in the section Inventory of goods. If you have configured online exchange with 1C, then click on the Download menu. In this case, all documents are loaded. Inventory of goods, edited documents will not be overwritten.

Tabular part

The correspondence of the barcode is searched in the device memory, if not found, then it is searched in the 1C database, if not found, it is searched in the 1C database in fixed assets. If a nomenclature is found as a result of the search, then a search will be performed in the tabular part of the document. If the object is found in the tabular section, then the quantity 1 + the quantity found in the tabular section will be added to this line. If the object is not found in the tabular section, then it will be added to the tabular section of the document with the actual quantity of 1 and the accounting quantity of 0. If the asset is found as a result of the search, the program will suggest adding it to the OS Inventory document.

Unloading documents in 1C

Inventory of fixed assets.

To conduct an inventory of fixed assets (hereinafter referred to as OS), it is necessary to prepare a document Inventory of OS without actual availability in 1C. Next, you need to go in the application to the OS Inventory section. If you have configured online exchange with 1C, then click on the Download menu. In this case, all documents are taken. Inventory of the OS, edited documents will not be overwritten.

If your application works offline, you can download documents from a file. The file is unloaded from 1C using processing.

Documents can be deleted all at once by clicking on Delete all or one by one, swiping left or right.

Tabular part

Having clicked on the necessary document the tabular part will open by analogy with 1C. The table part allows you to add / change / delete rows, edit the quantity.

Barcode scanning and processing

Barcodes can be scanned using the camera, hand scanner, GS-M100BT scanner, TSD Carible PL 50L or entered manually.

The barcode search algorithm is as follows:

The correspondence of the barcode is searched in the device memory, if not found, then it is searched in the 1C database. If the search result is found, then the search will be performed in the tabular part of the document. If the object is found in the tabular part, then the actual presence will be established in this line. If the object is not found in the tabular section, then it will be added to the tabular section of the document with actual presence.

Unloading documents in 1C

Completed documents are uploaded to 1C from the tabular menu.

By analogy with downloading, documents can be uploaded online in 1C or via a file.

Assign and print barcode items.

To set up a barcode and print labels, it is necessary to connect an external printed form in the Nomenclature card and click on Print barcode. If this item does not have a barcode, then a barcode is automatically generated and a label is printed. The label will be printed in size 60X30.

Assignment and printing of labels of fixed assets.

The OS directory code is used as a barcode for the OS. To print, you need to connect an external printing form and in the OS card click Print barcode. The label will be printed in size 60X30.

Settings

Description of settings.

Configuring the GS-M100BT bluetooth scanner.

On the Settings screen, you can configure the bluetooth barcode scanner GS-M100BT. For the first setup, you must first open "Bluetooth", the standard interface for pairing devices will open (it will look different on different devices).

Fast start

  • Install the application
  • Publish OData interface in 1C
  • Customize the composition of the OData interface
  • Download all directories, barcodes and documents from 1C into the application, either online or through a file.
  • Carry out warehouse operations
  • Upload processed data to 1C

 

It might be useful to read: