The publication covers all the possible (or almost all) options of programmed form open in the manageable application. The appearance of publication is related to the fact that 1С help and yellow books are very reticent on this topic. Often the simple tasks (for example, creation of catalog item based on) cause the difficulties even for the most experienced 1С developers who worked few with manageable application.
For openers, a small lyrical digression. I’ll tell you how NOT to open the form.
It is not allowed to use method GetForm(). It cannot be done for two reasons:
The first reason is that this method works off many times slower than methods OpenForm() or OpenFormModal().
The second reason is why such method is used at all. This is usually done when it is required to process in software the form before opening. For example, it is required to set the selection of dynamic list in the selection form. Let’s look at how usually the method “GetForm()” is used and what a mistake is in the usage of this method. The software code of opening the selection form with a choice looks like this:
The error here is that the code of software form processing may well be in conflict with the code of form event “OnCreateAtServer”. This may happen not at once. For example, the changes were made in the form module much later. And the developer who made the changes in the form module will be right. How could he know that his form is called from somewhere like that?
if you want your application to run in the Web Interface, it is best to refrain from the form open in the Modal mode. In this mode they are implemented as the pop-up windows that are disabled in the most browsers by default. Instead of Modal mode, it is possible to user the property of manageable form WindowOpeningMode = “Lock parent window”.
That’s all about inhibits, I will tell you how to open the form correctly.
1. How to open the object form using the reference to it
If it is necessary to open the main object form, then everything is very simple
2. How to open the selection form of arbitrary object
Simple open version: no additional software form processing is required. You just need to open the main selection form and get the selected value. Use method “InputValue()”:
&AtClient Procedure Command1(Command) Var SELValue; Array = New Array; Array.Add(Type("CatalogRef.Companies")); DescriptionTypes = New TypeDescription(Array); If InputValue(SELValue, "Input value", DescriptionTypes) Then Message(SELValue); EndIf; EndProcedure
If you specify several possible types, the program will prompt the user to select the type before selecting the value.
Use of method OpenForm()
First you need to examine the parameters of method “OpenForm()”. The full parameter list looks as follows:
, , , , , , , )
Everything is more or less clear with parameter “FormName”. And about such mysterious thing as “Parameters” (type – Structure) it is written very little in the 1С help. It is possible to pass there everything than can be passed from the client to the server. However, this information is obviously not enough. I’ll try to investigate all the possible options.
3. How to open the form of the existing object of reference type
The form of any object or registry record has th so-called hey attribute. It is highlighted in bold in the list of form attributes. To open the object form, it is required to add an item with Key “Key” and value — reference to the required object. For example:
&AtClient Procedure OpenProject(Command) P = New Structure; P.Insert("Key", Project); OpenForm("Catalog.Projects.ObjectForm", P); EndProcedure
4. Open the form of existing registry record
Very similar to the form open of the object of reference type, but in the item “Key” we pass the Key of registry record instead of reference. For example:
&AtClient Procedure OpenRegisterForm(Command) WriteKey = New Structure; WriteKey.Insert("Period", CurrentDate()); WriteKey.Insert("Employee", Employee); ArrayKey = New Array; ArrayKey.Add(WriteKey); KeyRegisterEntries = New("InformationRegisterRecordKey.Employees", ArrayKey); P = New Structure("Key", KeyRegisterEntries); OpenForm("InformationRegister.Employees.RecordForm", P); EndProcedure
5. How to open the form of new object with filling processing
It is even easier than to open the form of existing object. We just do not specify in the parameters “Key”.
P = New Structure; OpenForm("Catalog.Projects.ObjectForm", P);
In this case, the procedure “Filling” of the object module is called. This procedure has a single parameter “FillingData”. If we will insert in the parameters the key “FillingData”, it will be passed in the procedure “Filling”.
P = New Structure; P.Insert("FillingData", Project); OpenForm("Catalog.Projects.ObjectForm", P);
6. How to organize correctly the selection (sampling) in the table part
You should know that all the parameter specified in the parameter of method OpenForm() are available in the event “OnCreateAtServer” of opened form.
P = New Structure; P.Insert("Parameter", Project); OpenForm("Catalog.Projects.ChoiceForm", P);
Then in the event “OnCreateAtServer” of the item form of catalog Projects it will be possible to get “Parameter”. However, the form of catalog Projects can be opened from anywhere and this parameter may not be. Therefore, it is better to check that this parameter is really passed using this structure:
&AtServer Procedure OnCreateAtServer() If Parameters.Property("Parameter") Then SuppliedParameter = Parameters.Parameter; //Do something EndIf; EndProcedure
To perform the selection, it is necessary to know a few more moments. The first is the parameter of method “OpenForm”. As an owner, it may be another form or control element. This parameter will be available, firstly, in the property “FormOwner” of opened form, and, secondly, after the user performed the selection with standard way(i.e. using the selection form by clicking the button “Select”), the event “ChoiceProcessing” will occur at the Owner’s side.
P = New Structure; P.Insert("OurParameter", Project); OwnerFormSelection = Items.SubordinateProjects; OpenForm("Catalog.Projects.ChoiceForm", P, OwnerFormSelection);
In case when the selection is performed in a non-standard way, i.e. not the selection form is opened, but some arbitrary form, the you should use the methodNotifyChoice(), setting in the parameters the property of opened form CloseOnChoice = True. For example,
P = New Structure; P.Insert("OurParameter", Warehouse); P.Insert("CloseOnChoice ", True); OwnerFormSelection = Items.Goods; OpenForm("DataProcessor.SelectionNomenclature.Form", P, OwnerFormSelection);
In the form itself we organized the selection in software as follows:
&AtClient Procedure Select(Command) ResultSelecting = PrepareResultChoice(); NotifyChoice(ResultSelecting); EndProcedure &AtServer Function PrepareResultChoice() //Prepare result EndFunction
As a result of the execution of method NotifyChoice, the selection form will be closed and the event “ChoiceProcessing” will be called for the control element “Goods”.
Other utilities. In case of sampling it is possible to pass in the form the parameters whose names speak for themselves: “CloseOnChoice”, Multiselect, CloseOnOwnerClose. All the parameters have the type Boolean.
7. How to open the form and set in it the selection
Simple situation: simple selection by one or more attributes.
For example: Customer = SelectedCustomer And Organization = SelectedOrganization
To organize such selection, it is required to use the parameter “Filter”, type Structure, where Key is the Name of dynamic list field and the value is actually why it is required to filter data. For example:
P = New Structure; Filter = New Structure; Filter.Insert("Customer", SelectedCustomer); Filter.Insert("Organization", SelectedOrganization); P.Insert("Filter", Filter); OpenForm("Catalog.ContractsContractors.ChoiceForm", P);
In case if the selection is complex and it can be set only in software, you can go two ways.
First way (not the best).
Open the form, pass in it the parameter:
P = New Structure; P.Insert("Division", Division); OwnerFormSelection = Items.Employee; OpenForm("Catalog.Employees.ChoiceForm", P, OwnerFormSelection);
In the form itself in the event “OnCreateAtServer” set the list selection:
&AtServer Procedure OnCreateAtServer(Cancel, StandardProcessing) If Parameters.Property("Division") Then ListEmployees = PrepareListEmployees(Parameters.Division); NewItem = List.Filter.Items.Add(Type("DataCompositionFilterItem")); NewItem.LeftValue = New DataCompositionField("Reference"); NewItem.ComparisonType = DataCompositionComparisonType.InList; NewItem.RightValue = ListEmployees; NewItem.Application = DataCompositionFilterApplicationType.Items; EndIf; EndProcedure
Second way - the use of Selection Parameters and therefore it is better. Example:
&AtClient Procedure OnOpen(Cancel) NewParameter = New ChoiceParameter("Division", Object.Division); NewArray = New Array; NewArray.Add(NewParameter); NewParameters = New FixedArray(NewArray); Items.Employee.ChoiceParameters = NewParameters; EndProcedure
Why is it better to use the selection parameters:
1) We do not decline the standard selection processing: less code
2) Selection parameters will be available in the procedure “ChoiceDataGetProcessing” of the module of selected object manager. Therefore, we can limit the list of available selection values when entering by line.
Since the form cannot be opened modally, it is likely that the user can click several times the same button that opens the form. In order not to open the form each time and activate already opened form, it is required to fill the parameter “Unique”. The value type of this parameter is random, i.e. you can pass in it anything. it is convenient to pass in it the UUID of form that perform the opening.
FormOwner = Items.Staff; OpenForm("Catalog.Employees.Form", , FormOwner, ThisForm.UUID);
The platform will search the opened form with this uniqueness key. In case if it will find them, the existing window will be activated. Otherwise – a new one will be opened.