diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..4ff7e792 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ + + +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gradle" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 00000000..61307918 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,27 @@ +name: Java CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + java_version: ['11', '17'] + os: [ubuntu-latest, windows-latest, macOS-latest] + steps: + - uses: actions/checkout@v3 + - name: Set up JDK ${{ matrix.java_version }} + uses: actions/setup-java@v3.3.0 + with: + java-version: ${{ matrix.java_version }} + distribution: 'adopt' + - name: Build with Gradle + run: ./gradlew check --stacktrace + - name: Archive test results + if: failure() + uses: actions/upload-artifact@v3 + with: + name: junit_report_${{ matrix.os }}_${{ matrix.java_version }} + path: build/reports/tests/test diff --git a/.github/workflows/night_build.yml b/.github/workflows/night_build.yml new file mode 100644 index 00000000..f66afac1 --- /dev/null +++ b/.github/workflows/night_build.yml @@ -0,0 +1,40 @@ +name: Night build +on: + schedule: + - cron: '0 6 * * *' # run at 6 AM UTC + push: + branches: + - nigth_build + workflow_dispatch: + +jobs: + nightly: + name: Night build + runs-on: ubuntu-latest + steps: + - name: Checkout source + uses: actions/checkout@v3 + with: + ref: nigth_build + - name: Set up JDK + uses: actions/setup-java@v3.3.0 + with: + java-version: 11 + distribution: 'adopt' + - name: Build with Gradle + run: ./gradlew build + - name: Save file name + run: echo "PLUGIN_FILE_NAME=$(ls -t ./build/libs | head -1)" >> $GITHUB_ENV + - name: Save current date + run: echo "PLUGIN_CURRENT_DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV + - name: Deploy build + uses: WebFreak001/deploy-nightly@v1.1.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: https://uploads.github.com/repos/1c-syntax/sonar-bsl-plugin-community/releases/51033599/assets{?name,label} # find out this value by opening https://api.github.com/repos///releases in your browser and copy the full "upload_url" value including the {?name,label} part + release_id: 51033599 # same as above (id can just be taken out the upload_url, it's used to find old releases) + asset_path: ./build/libs/${{ env.PLUGIN_FILE_NAME }} # path to archive to upload + asset_name: sonar-communitybsl-plugin-nightly-${{ env.PLUGIN_CURRENT_DATE }}.jar # name, format is "-nightly-20210101" + asset_content_type: application/java-archive # required by GitHub API + max_releases: 7 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml new file mode 100644 index 00000000..b5093baf --- /dev/null +++ b/.github/workflows/qa.yml @@ -0,0 +1,28 @@ +name: QA + +on: + push: + branches: + - develop + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.event.repository.full_name + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: '' + - run: | + git fetch --prune --unshallow + - name: Set up JDK 11 + uses: actions/setup-java@v3.3.0 + with: + java-version: 11 + distribution: 'adopt' + - name: SonarCloud Scan + run: ./gradlew check sonarqube + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..cb9794ba --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Upload to release + +on: + release: + types: [published, edited] + +jobs: + build: + + runs-on: ubuntu-latest + name: Upload to release + + steps: + - name: Checkout source + uses: actions/checkout@v3 + - name: Set up JDK + uses: actions/setup-java@v3.3.0 + with: + java-version: 11 + distribution: 'adopt' + - name: Build with Gradle + run: ./gradlew build + - name: Upload jar to release + uses: AButler/upload-release-assets@v2.0 + with: + files: './build/libs/*.jar' + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index ead3f1b5..14edc643 100644 --- a/.gitignore +++ b/.gitignore @@ -58,14 +58,12 @@ build/ intellij-bsl/src/test/resources/parser/.idea/ gen/ -out/ # Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties \.idea/sonarlint-state\.xml \.idea/sonarlint\.xml +/.idea/jarRepositories.xml +/.idea/vcs.xml +/.idea/compiler.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 08bc7f5c..5108ea54 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,17 @@ - + + + + + + + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml index 8f27022c..62269dfc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/COPYING.LESSER.md b/COPYING.LESSER.md deleted file mode 100644 index 818d3033..00000000 --- a/COPYING.LESSER.md +++ /dev/null @@ -1,163 +0,0 @@ -GNU Lesser General Public License -================================= - -_Version 3, 29 June 2007_ -_Copyright © 2007 Free Software Foundation, Inc. <>_ - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - - -This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - -### 0. Additional Definitions - -As used herein, “this License” refers to version 3 of the GNU Lesser -General Public License, and the “GNU GPL” refers to version 3 of the GNU -General Public License. - -“The Library” refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - -An “Application” is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - -A “Combined Work” is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the “Linked -Version”. - -The “Minimal Corresponding Source” for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - -The “Corresponding Application Code” for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - -### 1. Exception to Section 3 of the GNU GPL - -You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - -### 2. Conveying Modified Versions - -If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - -* **a)** under this License, provided that you make a good faith effort to -ensure that, in the event an Application does not supply the -function or data, the facility still operates, and performs -whatever part of its purpose remains meaningful, or - -* **b)** under the GNU GPL, with none of the additional permissions of -this License applicable to that copy. - -### 3. Object Code Incorporating Material from Library Header Files - -The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - -* **a)** Give prominent notice with each copy of the object code that the -Library is used in it and that the Library and its use are -covered by this License. -* **b)** Accompany the object code with a copy of the GNU GPL and this license -document. - -### 4. Combined Works - -You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - -* **a)** Give prominent notice with each copy of the Combined Work that -the Library is used in it and that the Library and its use are -covered by this License. - -* **b)** Accompany the Combined Work with a copy of the GNU GPL and this license -document. - -* **c)** For a Combined Work that displays copyright notices during -execution, include the copyright notice for the Library among -these notices, as well as a reference directing the user to the -copies of the GNU GPL and this license document. - -* **d)** Do one of the following: - - **0)** Convey the Minimal Corresponding Source under the terms of this -License, and the Corresponding Application Code in a form -suitable for, and under terms that permit, the user to -recombine or relink the Application with a modified version of -the Linked Version to produce a modified Combined Work, in the -manner specified by section 6 of the GNU GPL for conveying -Corresponding Source. - - **1)** Use a suitable shared library mechanism for linking with the -Library. A suitable mechanism is one that **(a)** uses at run time -a copy of the Library already present on the user's computer -system, and **(b)** will operate properly with a modified version -of the Library that is interface-compatible with the Linked -Version. - -* **e)** Provide Installation Information, but only if you would otherwise -be required to provide such information under section 6 of the -GNU GPL, and only to the extent that such information is -necessary to install and execute a modified version of the -Combined Work produced by recombining or relinking the -Application with a modified version of the Linked Version. (If -you use option **4d0**, the Installation Information must accompany -the Minimal Corresponding Source and Corresponding Application -Code. If you use option **4d1**, you must provide the Installation -Information in the manner specified by section 6 of the GNU GPL -for conveying Corresponding Source.) - -### 5. Combined Libraries - -You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - -* **a)** Accompany the combined library with a copy of the same work based -on the Library, uncombined with any other library facilities, -conveyed under the terms of this License. -* **b)** Give prominent notice with the combined library that part of it -is a work based on the Library, and explaining where to find the -accompanying uncombined form of the same work. - -### 6. Revised Versions of the GNU Lesser General Public License - -The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License “or any later version” -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - -If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/COPYING.md b/COPYING.md deleted file mode 100644 index 2e4c51af..00000000 --- a/COPYING.md +++ /dev/null @@ -1,595 +0,0 @@ -GNU General Public License -========================== - -_Version 3, 29 June 2007_ -_Copyright © 2007 Free Software Foundation, Inc. <>_ - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -## Preamble - -The GNU General Public License is a free, copyleft license for software and other -kinds of works. - -The licenses for most software and other practical works are designed to take away -your freedom to share and change the works. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change all versions of a -program--to make sure it remains free software for all its users. We, the Free -Software Foundation, use the GNU General Public License for most of our software; it -applies also to any other work released this way by its authors. You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General -Public Licenses are designed to make sure that you have the freedom to distribute -copies of free software (and charge for them if you wish), that you receive source -code or can get it if you want it, that you can change the software or use pieces of -it in new free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you these rights or -asking you to surrender the rights. Therefore, you have certain responsibilities if -you distribute copies of the software, or if you modify it: responsibilities to -respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or for a fee, -you must pass on to the recipients the same freedoms that you received. You must make -sure that they, too, receive or can get the source code. And you must show them these -terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: **(1)** assert -copyright on the software, and **(2)** offer you this License giving you legal permission -to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that there is -no warranty for this free software. For both users' and authors' sake, the GPL -requires that modified versions be marked as changed, so that their problems will not -be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified versions of -the software inside them, although the manufacturer can do so. This is fundamentally -incompatible with the aim of protecting users' freedom to change the software. The -systematic pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we have designed -this version of the GPL to prohibit the practice for those products. If such problems -arise substantially in other domains, we stand ready to extend this provision to -those domains in future versions of the GPL, as needed to protect the freedom of -users. - -Finally, every program is threatened constantly by software patents. States should -not allow patents to restrict development and use of software on general-purpose -computers, but in those that do, we wish to avoid the special danger that patents -applied to a free program could make it effectively proprietary. To prevent this, the -GPL assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and modification follow. - -## TERMS AND CONDITIONS - -### 0. Definitions - -“This License” refers to version 3 of the GNU General Public License. - -“Copyright” also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - -“The Program” refers to any copyrightable work licensed under this -License. Each licensee is addressed as “you”. “Licensees” and -“recipients” may be individuals or organizations. - -To “modify” a work means to copy from or adapt all or part of the work in -a fashion requiring copyright permission, other than the making of an exact copy. The -resulting work is called a “modified version” of the earlier work or a -work “based on” the earlier work. - -A “covered work” means either the unmodified Program or a work based on -the Program. - -To “propagate” a work means to do anything with it that, without -permission, would make you directly or secondarily liable for infringement under -applicable copyright law, except executing it on a computer or modifying a private -copy. Propagation includes copying, distribution (with or without modification), -making available to the public, and in some countries other activities as well. - -To “convey” a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through a computer -network, with no transfer of a copy, is not conveying. - -An interactive user interface displays “Appropriate Legal Notices” to the -extent that it includes a convenient and prominently visible feature that **(1)** -displays an appropriate copyright notice, and **(2)** tells the user that there is no -warranty for the work (except to the extent that warranties are provided), that -licensees may convey the work under this License, and how to view a copy of this -License. If the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -### 1. Source Code - -The “source code” for a work means the preferred form of the work for -making modifications to it. “Object code” means any non-source form of a -work. - -A “Standard Interface” means an interface that either is an official -standard defined by a recognized standards body, or, in the case of interfaces -specified for a particular programming language, one that is widely used among -developers working in that language. - -The “System Libraries” of an executable work include anything, other than -the work as a whole, that **(a)** is included in the normal form of packaging a Major -Component, but which is not part of that Major Component, and **(b)** serves only to -enable use of the work with that Major Component, or to implement a Standard -Interface for which an implementation is available to the public in source code form. -A “Major Component”, in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system (if any) on which -the executable work runs, or a compiler used to produce the work, or an object code -interpreter used to run it. - -The “Corresponding Source” for a work in object code form means all the -source code needed to generate, install, and (for an executable work) run the object -code and to modify the work, including scripts to control those activities. However, -it does not include the work's System Libraries, or general-purpose tools or -generally available free programs which are used unmodified in performing those -activities but which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for the work, and -the source code for shared libraries and dynamically linked subprograms that the work -is specifically designed to require, such as by intimate data communication or -control flow between those subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can regenerate -automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same work. - -### 2. Basic Permissions - -All rights granted under this License are granted for the term of copyright on the -Program, and are irrevocable provided the stated conditions are met. This License -explicitly affirms your unlimited permission to run the unmodified Program. The -output from running a covered work is covered by this License only if the output, -given its content, constitutes a covered work. This License acknowledges your rights -of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, without -conditions so long as your license otherwise remains in force. You may convey covered -works to others for the sole purpose of having them make modifications exclusively -for you, or provide you with facilities for running those works, provided that you -comply with the terms of this License in conveying all material for which you do not -control copyright. Those thus making or running the covered works for you must do so -exclusively on your behalf, under your direction and control, on terms that prohibit -them from making any copies of your copyrighted material outside their relationship -with you. - -Conveying under any other circumstances is permitted solely under the conditions -stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - -### 3. Protecting Users' Legal Rights From Anti-Circumvention Law - -No covered work shall be deemed part of an effective technological measure under any -applicable law fulfilling obligations under article 11 of the WIPO copyright treaty -adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention -of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention of -technological measures to the extent such circumvention is effected by exercising -rights under this License with respect to the covered work, and you disclaim any -intention to limit operation or modification of the work as a means of enforcing, -against the work's users, your or third parties' legal rights to forbid circumvention -of technological measures. - -### 4. Conveying Verbatim Copies - -You may convey verbatim copies of the Program's source code as you receive it, in any -medium, provided that you conspicuously and appropriately publish on each copy an -appropriate copyright notice; keep intact all notices stating that this License and -any non-permissive terms added in accord with section 7 apply to the code; keep -intact all notices of the absence of any warranty; and give all recipients a copy of -this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you may offer -support or warranty protection for a fee. - -### 5. Conveying Modified Source Versions - -You may convey a work based on the Program, or the modifications to produce it from -the Program, in the form of source code under the terms of section 4, provided that -you also meet all of these conditions: - -* **a)** The work must carry prominent notices stating that you modified it, and giving a -relevant date. -* **b)** The work must carry prominent notices stating that it is released under this -License and any conditions added under section 7. This requirement modifies the -requirement in section 4 to “keep intact all notices”. -* **c)** You must license the entire work, as a whole, under this License to anyone who -comes into possession of a copy. This License will therefore apply, along with any -applicable section 7 additional terms, to the whole of the work, and all its parts, -regardless of how they are packaged. This License gives no permission to license the -work in any other way, but it does not invalidate such permission if you have -separately received it. -* **d)** If the work has interactive user interfaces, each must display Appropriate Legal -Notices; however, if the Program has interactive interfaces that do not display -Appropriate Legal Notices, your work need not make them do so. - -A compilation of a covered work with other separate and independent works, which are -not by their nature extensions of the covered work, and which are not combined with -it such as to form a larger program, in or on a volume of a storage or distribution -medium, is called an “aggregate” if the compilation and its resulting -copyright are not used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work in an aggregate -does not cause this License to apply to the other parts of the aggregate. - -### 6. Conveying Non-Source Forms - -You may convey a covered work in object code form under the terms of sections 4 and -5, provided that you also convey the machine-readable Corresponding Source under the -terms of this License, in one of these ways: - -* **a)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by the Corresponding Source fixed on a -durable physical medium customarily used for software interchange. -* **b)** Convey the object code in, or embodied in, a physical product (including a -physical distribution medium), accompanied by a written offer, valid for at least -three years and valid for as long as you offer spare parts or customer support for -that product model, to give anyone who possesses the object code either **(1)** a copy of -the Corresponding Source for all the software in the product that is covered by this -License, on a durable physical medium customarily used for software interchange, for -a price no more than your reasonable cost of physically performing this conveying of -source, or **(2)** access to copy the Corresponding Source from a network server at no -charge. -* **c)** Convey individual copies of the object code with a copy of the written offer to -provide the Corresponding Source. This alternative is allowed only occasionally and -noncommercially, and only if you received the object code with such an offer, in -accord with subsection 6b. -* **d)** Convey the object code by offering access from a designated place (gratis or for -a charge), and offer equivalent access to the Corresponding Source in the same way -through the same place at no further charge. You need not require recipients to copy -the Corresponding Source along with the object code. If the place to copy the object -code is a network server, the Corresponding Source may be on a different server -(operated by you or a third party) that supports equivalent copying facilities, -provided you maintain clear directions next to the object code saying where to find -the Corresponding Source. Regardless of what server hosts the Corresponding Source, -you remain obligated to ensure that it is available for as long as needed to satisfy -these requirements. -* **e)** Convey the object code using peer-to-peer transmission, provided you inform -other peers where the object code and Corresponding Source of the work are being -offered to the general public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded from the -Corresponding Source as a System Library, need not be included in conveying the -object code work. - -A “User Product” is either **(1)** a “consumer product”, which -means any tangible personal property which is normally used for personal, family, or -household purposes, or **(2)** anything designed or sold for incorporation into a -dwelling. In determining whether a product is a consumer product, doubtful cases -shall be resolved in favor of coverage. For a particular product received by a -particular user, “normally used” refers to a typical or common use of -that class of product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected to use, the -product. A product is a consumer product regardless of whether the product has -substantial commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - -“Installation Information” for a User Product means any methods, -procedures, authorization keys, or other information required to install and execute -modified versions of a covered work in that User Product from a modified version of -its Corresponding Source. The information must suffice to ensure that the continued -functioning of the modified object code is in no case prevented or interfered with -solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically for -use in, a User Product, and the conveying occurs as part of a transaction in which -the right of possession and use of the User Product is transferred to the recipient -in perpetuity or for a fixed term (regardless of how the transaction is -characterized), the Corresponding Source conveyed under this section must be -accompanied by the Installation Information. But this requirement does not apply if -neither you nor any third party retains the ability to install modified object code -on the User Product (for example, the work has been installed in ROM). - -The requirement to provide Installation Information does not include a requirement to -continue to provide support service, warranty, or updates for a work that has been -modified or installed by the recipient, or for the User Product in which it has been -modified or installed. Access to a network may be denied when the modification itself -materially and adversely affects the operation of the network or violates the rules -and protocols for communication across the network. - -Corresponding Source conveyed, and Installation Information provided, in accord with -this section must be in a format that is publicly documented (and with an -implementation available to the public in source code form), and must require no -special password or key for unpacking, reading or copying. - -### 7. Additional Terms - -“Additional permissions” are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. Additional -permissions that are applicable to the entire Program shall be treated as though they -were included in this License, to the extent that they are valid under applicable -law. If additional permissions apply only to part of the Program, that part may be -used separately under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any -additional permissions from that copy, or from any part of it. (Additional -permissions may be written to require their own removal in certain cases when you -modify the work.) You may place additional permissions on material, added by you to a -covered work, for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you add to a -covered work, you may (if authorized by the copyright holders of that material) -supplement the terms of this License with terms: - -* **a)** Disclaiming warranty or limiting liability differently from the terms of -sections 15 and 16 of this License; or -* **b)** Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices displayed by works -containing it; or -* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that -modified versions of such material be marked in reasonable ways as different from the -original version; or -* **d)** Limiting the use for publicity purposes of names of licensors or authors of the -material; or -* **e)** Declining to grant rights under trademark law for use of some trade names, -trademarks, or service marks; or -* **f)** Requiring indemnification of licensors and authors of that material by anyone -who conveys the material (or modified versions of it) with contractual assumptions of -liability to the recipient, for any liability that these contractual assumptions -directly impose on those licensors and authors. - -All other non-permissive additional terms are considered “further -restrictions” within the meaning of section 10. If the Program as you received -it, or any part of it, contains a notice stating that it is governed by this License -along with a term that is a further restriction, you may remove that term. If a -license document contains a further restriction but permits relicensing or conveying -under this License, you may add to a covered work material governed by the terms of -that license document, provided that the further restriction does not survive such -relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, in -the relevant source files, a statement of the additional terms that apply to those -files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form of a -separately written license, or stated as exceptions; the above requirements apply -either way. - -### 8. Termination - -You may not propagate or modify a covered work except as expressly provided under -this License. Any attempt otherwise to propagate or modify it is void, and will -automatically terminate your rights under this License (including any patent licenses -granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from a -particular copyright holder is reinstated **(a)** provisionally, unless and until the -copyright holder explicitly and finally terminates your license, and **(b)** permanently, -if the copyright holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently -if the copyright holder notifies you of the violation by some reasonable means, this -is the first time you have received notice of violation of this License (for any -work) from that copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses of -parties who have received copies or rights from you under this License. If your -rights have been terminated and not permanently reinstated, you do not qualify to -receive new licenses for the same material under section 10. - -### 9. Acceptance Not Required for Having Copies - -You are not required to accept this License in order to receive or run a copy of the -Program. Ancillary propagation of a covered work occurring solely as a consequence of -using peer-to-peer transmission to receive a copy likewise does not require -acceptance. However, nothing other than this License grants you permission to -propagate or modify any covered work. These actions infringe copyright if you do not -accept this License. Therefore, by modifying or propagating a covered work, you -indicate your acceptance of this License to do so. - -### 10. Automatic Licensing of Downstream Recipients - -Each time you convey a covered work, the recipient automatically receives a license -from the original licensors, to run, modify and propagate that work, subject to this -License. You are not responsible for enforcing compliance by third parties with this -License. - -An “entity transaction” is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an organization, or -merging organizations. If propagation of a covered work results from an entity -transaction, each party to that transaction who receives a copy of the work also -receives whatever licenses to the work the party's predecessor in interest had or -could give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if the predecessor -has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights granted or -affirmed under this License. For example, you may not impose a license fee, royalty, -or other charge for exercise of rights granted under this License, and you may not -initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging -that any patent claim is infringed by making, using, selling, offering for sale, or -importing the Program or any portion of it. - -### 11. Patents - -A “contributor” is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The work thus -licensed is called the contributor's “contributor version”. - -A contributor's “essential patent claims” are all patent claims owned or -controlled by the contributor, whether already acquired or hereafter acquired, that -would be infringed by some manner, permitted by this License, of making, using, or -selling its contributor version, but do not include claims that would be infringed -only as a consequence of further modification of the contributor version. For -purposes of this definition, “control” includes the right to grant patent -sublicenses in a manner consistent with the requirements of this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent license -under the contributor's essential patent claims, to make, use, sell, offer for sale, -import and otherwise run, modify and propagate the contents of its contributor -version. - -In the following three paragraphs, a “patent license” is any express -agreement or commitment, however denominated, not to enforce a patent (such as an -express permission to practice a patent or covenant not to sue for patent -infringement). To “grant” such a patent license to a party means to make -such an agreement or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the -Corresponding Source of the work is not available for anyone to copy, free of charge -and under the terms of this License, through a publicly available network server or -other readily accessible means, then you must either **(1)** cause the Corresponding -Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the -patent license for this particular work, or **(3)** arrange, in a manner consistent with -the requirements of this License, to extend the patent license to downstream -recipients. “Knowingly relying” means you have actual knowledge that, but -for the patent license, your conveying the covered work in a country, or your -recipient's use of the covered work in a country, would infringe one or more -identifiable patents in that country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, you -convey, or propagate by procuring conveyance of, a covered work, and grant a patent -license to some of the parties receiving the covered work authorizing them to use, -propagate, modify or convey a specific copy of the covered work, then the patent -license you grant is automatically extended to all recipients of the covered work and -works based on it. - -A patent license is “discriminatory” if it does not include within the -scope of its coverage, prohibits the exercise of, or is conditioned on the -non-exercise of one or more of the rights that are specifically granted under this -License. You may not convey a covered work if you are a party to an arrangement with -a third party that is in the business of distributing software, under which you make -payment to the third party based on the extent of your activity of conveying the -work, and under which the third party grants, to any of the parties who would receive -the covered work from you, a discriminatory patent license **(a)** in connection with -copies of the covered work conveyed by you (or copies made from those copies), or **(b)** -primarily for and in connection with specific products or compilations that contain -the covered work, unless you entered into that arrangement, or that patent license -was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied -license or other defenses to infringement that may otherwise be available to you -under applicable patent law. - -### 12. No Surrender of Others' Freedom - -If conditions are imposed on you (whether by court order, agreement or otherwise) -that contradict the conditions of this License, they do not excuse you from the -conditions of this License. If you cannot convey a covered work so as to satisfy -simultaneously your obligations under this License and any other pertinent -obligations, then as a consequence you may not convey it at all. For example, if you -agree to terms that obligate you to collect a royalty for further conveying from -those to whom you convey the Program, the only way you could satisfy both those terms -and this License would be to refrain entirely from conveying the Program. - -### 13. Use with the GNU Affero General Public License - -Notwithstanding any other provision of this License, you have permission to link or -combine any covered work with a work licensed under version 3 of the GNU Affero -General Public License into a single combined work, and to convey the resulting work. -The terms of this License will continue to apply to the part which is the covered -work, but the special requirements of the GNU Affero General Public License, section -13, concerning interaction through a network will apply to the combination as such. - -### 14. Revised Versions of this License - -The Free Software Foundation may publish revised and/or new versions of the GNU -General Public License from time to time. Such new versions will be similar in spirit -to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies that -a certain numbered version of the GNU General Public License “or any later -version” applies to it, you have the option of following the terms and -conditions either of that numbered version or of any later version published by the -Free Software Foundation. If the Program does not specify a version number of the GNU -General Public License, you may choose any version ever published by the Free -Software Foundation. - -If the Program specifies that a proxy can decide which future versions of the GNU -General Public License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the Program. - -Later license versions may give you additional or different permissions. However, no -additional obligations are imposed on any author or copyright holder as a result of -your choosing to follow a later version. - -### 15. Disclaimer of Warranty - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE -QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -### 16. Limitation of Liability - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY -COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS -PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, -INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE -OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE -WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -### 17. Interpretation of Sections 15 and 16 - -If the disclaimer of warranty and limitation of liability provided above cannot be -given local legal effect according to their terms, reviewing courts shall apply local -law that most closely approximates an absolute waiver of all civil liability in -connection with the Program, unless a warranty or assumption of liability accompanies -a copy of the Program in return for a fee. - -_END OF TERMS AND CONDITIONS_ - -## How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to -the public, the best way to achieve this is to make it free software which everyone -can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them -to the start of each source file to most effectively state the exclusion of warranty; -and each file should have at least the “copyright” line and a pointer to -where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like this -when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type 'show c' for details. - -The hypothetical commands `show w` and `show c` should show the appropriate parts of -the General Public License. Of course, your program's commands might be different; -for a GUI interface, you would use an “about box”. - -You should also get your employer (if you work as a programmer) or school, if any, to -sign a “copyright disclaimer” for the program, if necessary. For more -information on this, and how to apply and follow the GNU GPL, see -<>. - -The GNU General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may consider it -more useful to permit linking proprietary applications with the library. If this is -what you want to do, use the GNU Lesser General Public License instead of this -License. But first, please read -<>. diff --git a/LICENCE b/LICENCE new file mode 100644 index 00000000..153d416d --- /dev/null +++ b/LICENCE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/README.md b/README.md index 99754d1e..0c872764 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ # SonarQube 1C (BSL) Community Plugin -[![Build Status](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community.svg?branch=master)](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community) +[![Actions Status](https://github.com/1c-syntax/sonar-bsl-plugin-community/workflows/Java%20CI/badge.svg)](https://github.com/1c-syntax/sonar-bsl-plugin-community/actions) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=alert_status)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Maintainability](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=coverage)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) + +[![Download](https://img.shields.io/github/release/1c-syntax/sonar-bsl-plugin-community.svg?label=download&style=flat)](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases/latest) +[![Download night build](https://img.shields.io/github/workflow/status/1c-syntax/sonar-bsl-plugin-community/Night%20build/nigth_build?label=night%20build)](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases/v999.99.99) + [![telegram](https://img.shields.io/badge/telegram-chat-green.svg)](https://t.me/bsl_language_server) Поддержка языка 1С:Предприятие 8 и OneScript для [SonarQube](http://sonarqube.org). @@ -12,98 +16,10 @@ English version -> https://1c-syntax.github.io/sonar-bsl-plugin-community/en/ -## Возможности - -* Project "Overview" dashboard; -* Подсветка исходного кода 1С:Предприятие; -* Расчет базовых метрик, расчет количества строк кода; -* Регистрация диагностик, предоставляемых [BSL Language Server](https://1c-syntax.github.io/bsl-language-server) как внутренних правил; -* Встроенный анализатор - BSL Language Server Diagnostic provider -* Импорт результатов внешних анализаторов во внутреннем формате [json](https://1c-syntax.github.io/bsl-language-server/reporters/json.html); - -## Установка и обновление - -* Скачать jar-файл со страницы [релизов](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases) -* Разместить jar-файл согласно разделу Manual Installation [официальной документации](https://docs.sonarqube.org/latest/setup/install-plugin/) (по умолчанию - каталог `$SONARQUBE_HOME/extensions/plugins`) -* Перезапустить сервер - -## Требования - -Версия SonarQube | Версия плагина ------------------|---------------- -7.9+ | 0.7.0+ -7.4 - 7.8 | 0.1.0...0.6.0 - -Версия плагина | Версия JAVA ----------------|------------------ -1.0+ | 11 -0.1.0 - 0.6.0 | 8 - -## Запуск анализа - -### Настройка окружения - -Для анализа исходных кодов 1С используется утилита [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner). - -Утилите неоходимо указать параметры анализа одним из нижеперечисленных способов: -* в качестве аргументов командной строки, используя синтаксис -DимяПараметра=значениеПараметра -* используя файл `sonar-project.properties` - -Пример файла `sonar-project.properties`: - -```properties -# Ключ проекта. Уникальный в пределах сервера SonarQube -sonar.projectKey=my_project -# Имя проекта, отображаемое в интерфейсе SonarQube. Значение по умолчанию - ключ проекта. -sonar.projectName=My project -# Версия проекта -sonar.projectVersion=1.0 - -# Путь к исходным кодам. Относительные пути разрешаются от файла sonar-project.properties -# В качестве разделителя пути используется прямой слэш - /. Можно указать несколько каталогов через запятую. -sonar.sources=src - -# Кодировка файлов исходных кодов. -sonar.sourceEncoding=UTF-8 - -# Фильтры на включение в анализ. В примере ниже - только bsl и os файлы. -sonar.inclusions=**/*.bsl, **/*.os -``` - -Способы передачи параметров можно комбинировать. - -Если на сервере SonarQube включено требование принудительной авторизации и/или запрет анонимного анализа проектов, утилите sonar-scanner дополнительно нужно передавать токен авторизации, который можно получить согласно инструкции [User guide/User token](https://docs.sonarqube.org/latest/user-guide/user-token/) - -### Пример строки запуска - -```sh -sonar-scanner -Dsonar.host.url=http://sonar.company.com -Dsonar.login=SONAR_AUTH_TOKEN -``` - -## Настройки плагина - -* `sonar.bsl.languageserver.diagnosticLanguage` - язык имен правил и текстов сообщений сработавших правил от BSL Language Server. По умолчанию - `ru` - русский; -* `sonar.bsl.languageserver.enabled` - использование встроенного анализатора BSL Language Server Diagnostic provider при запуске анализа через `sonar-scanner`. По умолчанию - `true` - включен; -* `sonar.bsl.languageserver.reportPaths` - путь к файлам отчетов во внутреннем формате BSL Language Server - `json`. По умолчанию - `""` - не заполнено. - -## Интеграция с BSL Language Server - -По умолчанию в качестве анализатора используется встроенный провайдер диагностик из BSL Language Server. - -Выполнение анализа встроенным анализатором можно отключить, установив параметру `sonar.bsl.languageserver.enabled` значение `false` через командную строку или файл настроек. - -```sh -sonar-scanner -Dsonar.bsl.languageserver.enabled=false -``` - -> Отключение анализатора не отключает процесс парсинга файлов. Расчет метрик и подсветка синтаксиса будут работать вне зависимости от значения настройки. - -### Импорт результатов из внешнего файла - -[BSL Language Server](https://github.com/1c-syntax/bsl-language-server) может запускать анализ исходного кода и выдавать список обнаруженых диагностик в виде json-файла. Инструкция по запуску BSL Language Server в режиме анализа расположена на странице проекта. - -Для импорта результата при запуске утилиты sonar-scanner нужно передать параметр `sonar.bsl.languageserver.reportPaths` через аргументы командной строки или через файл `sonar-project.properties`, в котором указать путь к файлу (или файлам, через запятую) с результатами анализа. +## Матрица соответствия версий -```sh -sonar-scanner -Dsonar.bsl.languageserver.reportPaths=./bsl-json.json -``` +Версия SonarQube | Версия плагина | Версия JAVA +-----------------|----------------|------------------ +8.9+ | 1.11.0+ | 11 +7.9+ | 0.7.0...1.10.0 | 11 +7.4 - 7.8 | 0.1.0...0.6.0 | 8 diff --git a/build.gradle.kts b/build.gradle.kts index 3c664cb4..5542ae01 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,133 +1,152 @@ -import java.net.URI -import java.util.* - -plugins { - jacoco - java - maven - id("org.sonarqube") version "2.8" - id("com.github.hierynomus.license") version "0.15.0" - id("com.github.johnrengelman.shadow") version("5.1.0") - id("com.github.ben-manes.versions") version "0.25.0" - id("com.github.gradle-git-version-calculator") version "1.1.0" -} - -group = "com.github.1c-syntax" -version = gitVersionCalculator.calculateVersion("v") - -repositories { - mavenCentral() - maven { - url = URI("https://jitpack.io") - } -} - -dependencies { - implementation("org.sonarsource.sonarqube:sonar-plugin-api:7.9") - - compile("com.github.1c-syntax:bsl-language-server:1043a57e84338cf17f7df108e77b6cb05f8f694f") - compile("com.fasterxml.jackson.core:jackson-databind:2.10.0") - compile("com.google.code.findbugs:jsr305:3.0.2") - // https://mvnrepository.com/artifact/org.sonarsource.analyzer-commons/sonar-analyzer-commons - compile("org.sonarsource.analyzer-commons:sonar-analyzer-commons:1.11.0.541") - - // MD to HTML converter of BSL LS rule descriptions - compile("com.atlassian.commonmark:commonmark:0.13.0") - compile("com.atlassian.commonmark:commonmark-ext-gfm-tables:0.13.0") - compile("com.atlassian.commonmark:commonmark-ext-autolink:0.13.0") - compile("com.atlassian.commonmark:commonmark-ext-heading-anchor:0.13.0") - - compile("me.tongfei:progressbar:0.7.4") - - testImplementation("org.junit.jupiter:junit-jupiter-api:5.5.2") - testRuntime("org.junit.jupiter:junit-jupiter-engine:5.5.2") - - testCompile("org.assertj:assertj-core:3.13.2") - testCompile("org.mockito:mockito-core:3.1.0") -} - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -tasks.withType { - options.encoding = "UTF-8" - options.compilerArgs.add("-Xlint:unchecked") -} - -tasks.test { - useJUnitPlatform() - - testLogging { - events("passed", "skipped", "failed") - } - - reports { - html.isEnabled = true - } -} - -jacoco { - toolVersion = "0.8.2" -} - -tasks.jacocoTestReport { - reports { - xml.isEnabled = true - } -} - -license { - header = rootProject.file("license/HEADER.txt") - ext["year"] = Calendar.getInstance().get(Calendar.YEAR) - ext["name"] = "Nikita Gryzlov " - ext["project"] = "SonarQube 1C (BSL) Community Plugin" - strictCheck = true - mapping("java", "SLASHSTAR_STYLE") - exclude("**/*.properties") - exclude("**/*.bsl") - exclude("**/*.json") -} - -sonarqube { - properties { - property("sonar.sourceEncoding", "UTF-8") - property("sonar.host.url", "https://sonarcloud.io") - property("sonar.organization", "1c-syntax") - property("sonar.projectKey", "1c-syntax_sonar-bsl-plugin-community") - property("sonar.projectName", "SonarQube 1C (BSL) Community Plugin") - property("sonar.exclusions", "**/gen/**/*.*") - } -} - -tasks.jar { - manifest { - attributes["Plugin-Key"] = "communitybsl" - attributes["Plugin-Description"] = "Code Analyzer for 1C (BSL)" - attributes["Plugin-Class"] = "com.github._1c_syntax.bsl.sonar.BSLPlugin" - attributes["Plugin-Name"] = "1C (BSL) Community Plugin" - attributes["Plugin-Version"] = "${project.version}" - - attributes["Plugin-License"] = "GNU LGPL v3" - - attributes["Plugin-Homepage"] = "https://1c-syntax.github.io/sonar-bsl-plugin-community" - attributes["Plugin-IssueTrackerUrl"] = "https://github.com/1c-syntax/sonar-bsl-plugin-community/issues" - attributes["Plugin-SourcesUrl"] = "https://github.com/1c-syntax/sonar-bsl-plugin-community" - attributes["Plugin-Developers"] = "Nikita Gryzlov" - - attributes["SonarLint-Supported"] = true - attributes["Sonar-Version"] = "7.9" - - attributes["Plugin-Organization"] = "1c-syntax" - attributes["Plugin-OrganizationUrl"] = "https://github.com/1c-syntax" - } - configurations["compile"].forEach { - from(zipTree(it.absoluteFile)) { - exclude("META-INF/MANIFEST.MF") - exclude("META-INF/*.SF") - exclude("META-INF/*.DSA") - exclude("META-INF/*.RSA") - } - } -} +import java.net.URI +import java.util.* + +plugins { + jacoco + java + `maven-publish` + id("org.sonarqube") version "3.3" + id("org.cadixdev.licenser") version "0.6.1" + id("com.github.johnrengelman.shadow") version("7.0.0") + id("com.github.ben-manes.versions") version "0.42.0" + id("com.github.gradle-git-version-calculator") version "1.1.0" + id("io.freefair.lombok") version "6.4.3" +} + +group = "io.github.1c-syntax" +version = gitVersionCalculator.calculateVersion("v") + +repositories { + mavenLocal() + mavenCentral() + maven { + url = URI("https://s01.oss.sonatype.org/content/repositories/snapshots") + } + maven { + url = URI("https://jitpack.io") + } +} + +val commonmarkVersion = "0.17.0" +val sonarQubeVersion = "8.9.0.43852" + +dependencies { + implementation("org.sonarsource.sonarqube", "sonar-plugin-api", sonarQubeVersion) + + implementation("io.github.1c-syntax", "bsl-language-server", "0.20.0") + + implementation("org.apache.commons:commons-lang3:3.12.0") + implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3") + + // https://mvnrepository.com/artifact/org.sonarsource.analyzer-commons/sonar-analyzer-commons + implementation("org.sonarsource.analyzer-commons:sonar-analyzer-commons:1.25.0.1003") + + // MD to HTML converter of BSL LS rule descriptions + implementation("com.atlassian.commonmark", "commonmark", commonmarkVersion) + implementation("com.atlassian.commonmark", "commonmark-ext-gfm-tables", commonmarkVersion) + implementation("com.atlassian.commonmark", "commonmark-ext-autolink", commonmarkVersion) + implementation("com.atlassian.commonmark", "commonmark-ext-heading-anchor", commonmarkVersion) + + implementation("me.tongfei:progressbar:0.9.3") + + compileOnly("com.google.code.findbugs:jsr305:3.0.2") + + testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.8.0") + testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.8.0") + + testImplementation("org.assertj:assertj-core:3.22.0") + testImplementation("org.mockito:mockito-core:4.5.1") + + testImplementation("org.sonarsource.sonarqube", "sonar-testing-harness", sonarQubeVersion) + testImplementation("org.sonarsource.sonarqube", "sonar-core", sonarQubeVersion) + testImplementation("org.reflections", "reflections", "0.9.12") +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +tasks.withType { + options.encoding = "UTF-8" + options.compilerArgs.add("-Xlint:unchecked") +} + +tasks.test { + useJUnitPlatform() + + testLogging { + events("passed", "skipped", "failed") + } + + reports { + html.required.set(true) + } +} + +tasks.check { + dependsOn(tasks.jacocoTestReport) +} + +tasks.jacocoTestReport { + reports { + xml.required.set(true) + xml.outputLocation.set(File("$buildDir/reports/jacoco/test/jacoco.xml")) + } +} + +license { + header(rootProject.file("license/HEADER.txt")) + newLine(false) + ext["year"] = Calendar.getInstance().get(Calendar.YEAR) + ext["name"] = "Alexey Sosnoviy , Nikita Fedkin " + ext["project"] = "SonarQube 1C (BSL) Community Plugin" + exclude("**/*.properties") + exclude("**/*.bsl") + exclude("**/*.json") +} + +sonarqube { + properties { + property("sonar.sourceEncoding", "UTF-8") + property("sonar.host.url", "https://sonarcloud.io") + property("sonar.organization", "1c-syntax") + property("sonar.projectKey", "1c-syntax_sonar-bsl-plugin-community") + property("sonar.projectName", "SonarQube 1C (BSL) Community Plugin") + property("sonar.exclusions", "**/gen/**/*.*") + property("sonar.coverage.jacoco.xmlReportPaths", "$buildDir/reports/jacoco/test/jacoco.xml") + } +} + +tasks.jar { + manifest { + attributes["Plugin-Key"] = "communitybsl" + attributes["Plugin-Description"] = "Code Analyzer for 1C (BSL)" + attributes["Plugin-Class"] = "com.github._1c_syntax.bsl.sonar.BSLPlugin" + attributes["Plugin-Name"] = "1C (BSL) Community Plugin" + attributes["Plugin-Version"] = "${project.version}" + + attributes["Plugin-License"] = "GNU LGPL v3" + + attributes["Plugin-Homepage"] = "https://1c-syntax.github.io/sonar-bsl-plugin-community" + attributes["Plugin-IssueTrackerUrl"] = "https://github.com/1c-syntax/sonar-bsl-plugin-community/issues" + attributes["Plugin-SourcesUrl"] = "https://github.com/1c-syntax/sonar-bsl-plugin-community" + attributes["Plugin-Developers"] = "Alexey Sosnoviy, Nikita Fedkin" + + attributes["SonarLint-Supported"] = false + attributes["Sonar-Version"] = sonarQubeVersion + + attributes["Plugin-Organization"] = "1c-syntax" + attributes["Plugin-OrganizationUrl"] = "https://github.com/1c-syntax" + } + + + enabled = false + dependsOn(tasks.shadowJar) +} + +tasks.shadowJar { + project.configurations.implementation.get().isCanBeResolved = true + configurations = listOf(project.configurations["implementation"]) + archiveClassifier.set("") +} diff --git a/docs/en/index.md b/docs/en/index.md index 4ed9c72c..ef03177f 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,6 +1,7 @@ # SonarQube 1C (BSL) Community Plugin -[![Build Status](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community.svg?branch=master)](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community) +[![Actions Status](https://github.com/1c-syntax/sonar-bsl-plugin-community/workflows/Java%20CI/badge.svg)](https://github.com/1c-syntax/sonar-bsl-plugin-community/actions) +[![Download](https://img.shields.io/github/release/1c-syntax/sonar-bsl-plugin-community.svg?label=download&style=flat)](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases/latest) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=alert_status)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Maintainability](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=coverage)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) @@ -25,17 +26,13 @@ - Put the jar file according to Manual Installation [section of official documentation](https://docs.sonarqube.org/latest/setup/install-plugin/) (default - `$SONARQUBE_HOME/extensions/plugins`) - Restart server -## Requirements +## Version matrix -SonarQube Version | Plugin Version -------------------|------------------ -7.9+ | 0.7.0+ -7.4 - 7.8 | 0.1.0...0.6.0 - -Plugin Version | JAVA Version ----------------|---------------- -1.0+ | 11 -0.1.0 - 0.6.0 | 8 +SonarQube Version | Plugin Version | JAVA version +------------------|----------------|------------------ +8.9+ | 1.11.0+ | 11 +7.9+ | 0.7.0...1.10.0 | 11 +7.4 - 7.8 | 0.1.0...0.6.0 | 8 ## Run analysis @@ -84,8 +81,15 @@ sonar-scanner -Dsonar.host.url=http://sonar.company.com -Dsonar.login=SONAR_AUTH - `sonar.bsl.languageserver.diagnosticLanguage` - the language of the rule names and message text of the triggered rules from the BSL Language Server. Default - `ru` - Russian; - `sonar.bsl.languageserver.enabled` - use the built-in BSL Language Server Diagnostic provider analyzer when running analysis via `sonar-scanner`. Default - `true` - enabled; - `sonar.bsl.languageserver.reportPaths` - the path to the report files in the internal format to the BSL Language Server - `json`. By default - `""` - not filled. -* `sonar.bsl.file.suffixes` - list of file suffixes that will be scanned. Default - `.bsl,.os` -- `sonar.bsl.calculateLineCover` - calculate locations for coverage. +- `sonar.bsl.languageserver.skipSupport` - skip computing diagnostics according to module's support mode. *Only if there is a parent configuration*. In sonar-project.properties the value is specified without quote. +Available values: + * with support locked - modules for support with the prohibition of changes will be skipped ("locked"); + * with support - modules on support will be skipped; + * never *default* - modules are not skipped +- `sonar.bsl.languageserver.overrideConfiguration` - override Quality Profile settings with settings from BSL Language Server configuration file; +- `sonar.bsl.languageserver.configurationPath` - path to BSL Language Server configuration file to override settings; +- `sonar.bsl.file.suffixes` - list of file suffixes that will be scanned. Default - `.bsl,.os` + ## Language switch for rule names/descriptions and issue messages Plugin contains support of two languages for rule names/descriptions and issue messages: @@ -129,21 +133,5 @@ To import the result to sonar-scanner utility, pass the parameter `sonar.bsl.lan sonar-scanner -Dsonar.bsl.languageserver.reportPaths=./bsl-json.json ``` -### Calculate loc for cover - -Calculate locations for coverage. Use for correct code coverage when using genericCoverage.xml which contains only covered lines. - -``` -sonar.bsl.calculateLineCover=true -sonar.coverageReportPaths=./genericCoverage.xml -``` - -```xml - - - - - - -``` - +### Calculate loc for cover (Deprecated) +Use Coverage41C as full coverage report generator. diff --git a/docs/index.md b/docs/index.md index 757711f2..3adc0323 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,9 +1,13 @@ # SonarQube 1C (BSL) Community Plugin -[![Build Status](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community.svg?branch=master)](https://travis-ci.org/1c-syntax/sonar-bsl-plugin-community) +[![Actions Status](https://github.com/1c-syntax/sonar-bsl-plugin-community/workflows/Java%20CI/badge.svg)](https://github.com/1c-syntax/sonar-bsl-plugin-community/actions) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=alert_status)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Maintainability](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=1c-syntax_sonar-bsl-plugin-community&metric=coverage)](https://sonarcloud.io/dashboard?id=1c-syntax_sonar-bsl-plugin-community) + +[![Download](https://img.shields.io/github/release/1c-syntax/sonar-bsl-plugin-community.svg?label=download&style=flat)](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases/latest) +[![Download night build](https://img.shields.io/github/workflow/status/1c-syntax/sonar-bsl-plugin-community/Night%20build/nigth_build?label=night%20build)](https://github.com/1c-syntax/sonar-bsl-plugin-community/releases/v999.99.99) + [![telegram](https://img.shields.io/badge/telegram-chat-green.svg)](https://t.me/bsl_language_server) Поддержка языка 1С:Предприятие 8 и OneScript для [SonarQube](http://sonarqube.org). @@ -16,7 +20,7 @@ * Подсветка исходного кода 1С:Предприятие; * Расчет базовых метрик, расчет количества строк кода; * Регистрация диагностик, предоставляемых [BSL Language Server](https://1c-syntax.github.io/bsl-language-server) как внутренних правил; -* Встроенный анализатор - BSL Language Server Diagnostic provider +* Встроенный анализатор - BSL Language Server Diagnostic provider * Импорт результатов внешних анализаторов во внутреннем формате [json](https://1c-syntax.github.io/bsl-language-server/reporters/json.html); ## Установка и обновление @@ -25,17 +29,13 @@ * Разместить jar-файл согласно разделу Manual Installation [официальной документации](https://docs.sonarqube.org/latest/setup/install-plugin/) (по умолчанию - каталог `$SONARQUBE_HOME/extensions/plugins`) * Перезапустить сервер -## Требования +## Матрица соответствия версий -Версия SonarQube | Версия плагина ------------------|---------------- -7.9+ | 0.7.0+ -7.4 - 7.8 | 0.1.0...0.6.0 - -Версия плагина | Версия JAVA ----------------|------------------ -1.0+ | 11 -0.1.0 - 0.6.0 | 8 +Версия SonarQube | Версия плагина | Версия JAVA +-----------------|----------------|------------------ +8.9+ | 1.11.0+ | 11 +7.9+ | 0.7.0...1.10.0 | 11 +7.4 - 7.8 | 0.1.0...0.6.0 | 8 ## Запуск анализа @@ -43,8 +43,8 @@ Для анализа исходных кодов 1С используется утилита [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner). -Утилите неоходимо указать параметры анализа одним из нижеперечисленных способов: -* в качестве аргументов командной строки, используя синтаксис -DимяПараметра=значениеПараметра +Утилите необходимо указать параметры анализа одним из нижеперечисленных способов: +* в качестве аргументов командной строки, используя синтаксис `-DимяПараметра=значениеПараметра` * используя файл `sonar-project.properties` Пример файла `sonar-project.properties`: @@ -74,8 +74,8 @@ sonar.inclusions=**/*.bsl, **/*.os ### Пример строки запуска -```sh -sonar-scanner -Dsonar.host.url=http://sonar.company.com -Dsonar.login=SONAR_AUTH_TOKEN +```shell +sonar-scanner -Dsonar.host.url=https://sonar.company.com -Dsonar.login=SONAR_AUTH_TOKEN ``` ## Настройки плагина @@ -83,8 +83,14 @@ sonar-scanner -Dsonar.host.url=http://sonar.company.com -Dsonar.login=SONAR_AUTH * `sonar.bsl.languageserver.diagnosticLanguage` - язык имен правил и текстов сообщений сработавших правил от BSL Language Server. По умолчанию - `ru` - русский; * `sonar.bsl.languageserver.enabled` - использование встроенного анализатора BSL Language Server Diagnostic provider при запуске анализа через `sonar-scanner`. По умолчанию - `true` - включен; * `sonar.bsl.languageserver.reportPaths` - путь к файлам отчетов во внутреннем формате BSL Language Server - `json`. По умолчанию - `""` - не заполнено. +* `sonar.bsl.languageserver.skipSupport` - пропустить расчет диагностик в зависимости от режима поддержки модуля. *Только при наличии конфигурации поставщика*. В файле sonar-project.properties значения указываются без кавычек. + Доступные значения: + - with support locked - будут пропускаться модули на поддержке с запретом изменения (*"на замке"*); + - with support - будут пропускаться модули на поддержке; + - never *по умолчанию* - модули не пропускаются; +* `sonar.bsl.languageserver.overrideConfiguration` - переопределить настройки Quality Profile настройками из файла конфигурации BSL Language Server; +* `sonar.bsl.languageserver.configurationPath` - путь к файлу конфигурации BSL Language Server для переопределения настроек; * `sonar.bsl.file.suffixes` - список расширений файлов для анализа. По умолчанию - `.bsl,.os` -* `sonar.bsl.calculateLineCover` - расчитывать строки для покрытия тестами. По умолчанию - `false` - выключен ## Переключение языка имен правил и сообщений в замечаниях @@ -113,7 +119,7 @@ http://localhost:9000/project/settings?category=1c+%28bsl%29&id=projectKey Выполнение анализа встроенным анализатором можно отключить, установив параметру `sonar.bsl.languageserver.enabled` значение `false` через командную строку или файл настроек. -```sh +```shell sonar-scanner -Dsonar.bsl.languageserver.enabled=false ``` @@ -121,30 +127,47 @@ sonar-scanner -Dsonar.bsl.languageserver.enabled=false ### Импорт результатов из внешнего файла -[BSL Language Server](https://github.com/1c-syntax/bsl-language-server) может запускать анализ исходного кода и выдавать список обнаруженых диагностик в виде json-файла. Инструкция по запуску BSL Language Server в режиме анализа расположена на странице проекта. +[BSL Language Server](https://github.com/1c-syntax/bsl-language-server) может запускать анализ исходного кода и выдавать список обнаруженных замечаний в виде json-файла. Инструкция по запуску `BSL Language Server` в режиме анализа расположена на странице проекта. -Для импорта результата при запуске утилиты sonar-scanner нужно передать параметр `sonar.bsl.languageserver.reportPaths` через аргументы командной строки или через файл `sonar-project.properties`, в котором указать путь к файлу (или файлам, через запятую) с результатами анализа. +Для импорта результата при запуске утилиты `sonar-scanner` нужно передать параметр `sonar.bsl.languageserver.reportPaths` через аргументы командной строки или через файл `sonar-project.properties`, в котором указать путь к файлу (или файлам, через запятую) с результатами анализа. -```sh +```shell sonar-scanner -Dsonar.bsl.languageserver.reportPaths=./bsl-json.json ``` -### Расчет строк для покрытия тестами +### Расчет строк для покрытия тестами (Устарело) -Расчитывает строки которые должны быть покрыты тестами. Используется для корректного подсчета процента покрытия при - импорте файлов genericCoverage.xml содержащих только покрытые строки. +Для расчета строк покрытия используйте утилиту Coverage41C или подобную, возвращающую полные данные по покрытию. -``` -sonar.bsl.calculateLineCover=true -sonar.coverageReportPaths=./genericCoverage.xml -``` +## Интеграция с Автоматизированная проверка конфигураций + +*Доступна с версии 1.6* + +Включить добавление правил и профилей из АПК можно установив свойство `sonar.bsl.acc.enable` +После включения при загрузке файла с ошибками из АПК в формате json будет происходить сопоставление +с внутренними правилами. Это дает возможность управлять ошибками импортируемыми из АПК на стороне sonarqube. + +**Важно** Так как ключом правила является код ошибки из АПК, то сопоставление работает только если при выгрузке ошибок +обработкой [acc-export](https://github.com/otymko/acc-export) указать acc.titleError=code -```xml - - - - - - +Cвойство `sonar.bsl.acc.accRulesPaths`. Правила из поставки можно расширить за счет свойих внешних файлов в формате: ``` - +{ + "Rules": [ + { + "Code": "96", // Код ошибки + "Type": "BUG", // Nbg ошибки + "Severity": "CRITICAL", // Серьезность ошибки + "Name": "Использована конструкция \"ОБЪЕДИНИТЬ\".", // Имя правила + "Description": "

Использование ключевых слов \"ОБЪЕДИНИТЬ\" и \"ОБЪЕДИНИТЬ ВСЕ\" в запросах

#std434

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

В общем случае, при объединении в запросе результатов нескольких запросов следует использовать конструкцию ОБЪЕДИНИТЬ ВСЕ, а не ОБЪЕДИНИТЬ. Поскольку во втором варианте, при объединении запросов полностью одинаковые строки заменяются одной, на что затрачивается дополнительное время, даже в случаях, когда одинаковых строк в запросах заведомо быть не может.

\n

Исключением являются ситуации, когда выполнение замены нескольких одинаковых строк одной является необходимым условием выполнения запроса.

Правильно:

\n

ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

\n

Неправильно:

\n

ВЫБРАТЬ
ПоступлениеТоваровУслуг.Ссылка
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

ОБЪЕДИНИТЬ

ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

", // Описание в формате HTML без заголовков и стилей + "Active": true, // Признак активности по умолчанию + "NeedForCertificate": false, // Признак включения в профиль для сертификации + "EffortMinutes": 0 // Время на исправление + } + ] +} +``` + +Cвойство `sonar.bsl.acc.createExternalIssues`. Определяет как поступить с ошибками, которые были в файле, но для них +не было найдено активного правила. Для фильтрации ошибок поступающих от АПК на строне sonarqube потребуется отключить +свойство. diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf0..7454180f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7c4388a9..41dfb879 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 83f2acfd..1b6c7873 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,113 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -105,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 24467a14..ac1b06f9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 00000000..fb6de208 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,4 @@ +before_install: + - source ~/.sdkman/bin/sdkman-init.sh + - sdk install java 16.0.0.hs-adpt + - sdk use java 16.0.0.hs-adpt diff --git a/license/HEADER.txt b/license/HEADER.txt index 34f46517..4380b8a4 100644 --- a/license/HEADER.txt +++ b/license/HEADER.txt @@ -1,6 +1,6 @@ This file is a part of ${project}. -Copyright © 2018-${year} +Copyright (c) 2018-${year} ${name} SPDX-License-Identifier: LGPL-3.0-or-later diff --git a/lombok.config b/lombok.config new file mode 100644 index 00000000..2e9a5449 --- /dev/null +++ b/lombok.config @@ -0,0 +1,2 @@ +lombok.anyConstructor.addConstructorProperties=true +lombok.addLombokGeneratedAnnotation=true diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCommunityProperties.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCommunityProperties.java index 01a5ee3f..dfa15722 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCommunityProperties.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCommunityProperties.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,29 +21,40 @@ */ package com.github._1c_syntax.bsl.sonar; -import com.github._1c_syntax.bsl.languageserver.configuration.DiagnosticLanguage; +import com.github._1c_syntax.bsl.languageserver.configuration.Language; +import com.github._1c_syntax.bsl.languageserver.configuration.diagnostics.SkipSupport; import org.sonar.api.PropertyType; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Qualifiers; import java.util.Arrays; import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.Stream; + public final class BSLCommunityProperties { public static final String LANG_SERVER_DIAGNOSTIC_LANGUAGE_KEY = "sonar.bsl.languageserver.diagnosticLanguage"; + public static final String LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_KEY = "sonar.bsl.languageserver.skipSupport"; public static final String LANG_SERVER_ENABLED_KEY = "sonar.bsl.languageserver.enabled"; + public static final String LANG_SERVER_CONFIGURATION_PATH_KEY = "sonar.bsl.languageserver.configurationPath"; + public static final String LANG_SERVER_OVERRIDE_CONFIGURATION_KEY = "sonar.bsl.languageserver.overrideConfiguration"; public static final String LANG_SERVER_REPORT_PATH_KEY = "sonar.bsl.languageserver.reportPaths"; public static final String BSL_FILE_EXTENSIONS_KEY = "sonar.bsl.file.suffixes"; - public static final String BSL_CALCULATE_LINE_TO_COVER_KEY = "sonar.bsl.calculateLineCover"; public static final Boolean LANG_SERVER_ENABLED_DEFAULT_VALUE = Boolean.TRUE; - public static final String LANG_SERVER_DIAGNOSTIC_LANGUAGE_DEFAULT_VALUE = DiagnosticLanguage.RU.getLanguageCode(); + public static final String LANG_SERVER_DIAGNOSTIC_LANGUAGE_DEFAULT_VALUE = Language.RU.getLanguageCode(); + public static final String LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_DEFAULT_VALUE + = SkipSupport.NEVER.name().toLowerCase(Locale.ENGLISH); + + public static final String LANG_SERVER_CONFIGURATION_PATH_DEFAULT_VALUE = ".bsl-language-server.json"; + public static final Boolean LANG_SERVER_OVERRIDE_CONFIGURATION_DEFAULT_VALUE = Boolean.FALSE; public static final String BSL_FILE_EXTENSIONS_DEFAULT_VALUE = ".bsl,.os"; - public static final Boolean BSL_CALCULATE_LINE_TO_COVER_VALUE = Boolean.FALSE; + public static final String BSL_CATEGORY = "1C (BSL)"; private static final String EXTERNAL_ANALYZERS_CATEGORY = "External Analyzers"; - private static final String BSL_CATEGORY = "1C (BSL)"; private static final String BSL_SUBCATEGORY = "1C (BSL) Community"; @@ -60,7 +71,7 @@ public static List getProperties() { ) .defaultValue(LANG_SERVER_DIAGNOSTIC_LANGUAGE_DEFAULT_VALUE) .type(PropertyType.SINGLE_SELECT_LIST) - .options(DiagnosticLanguage.RU.getLanguageCode(), DiagnosticLanguage.EN.getLanguageCode()) + .options(Language.RU.getLanguageCode(), Language.EN.getLanguageCode()) .category(BSL_CATEGORY) .onQualifiers(Qualifiers.APP, Qualifiers.PROJECT) .index(0) @@ -74,24 +85,47 @@ public static List getProperties() { .onQualifiers(Qualifiers.PROJECT) .index(1) .build(), - PropertyDefinition.builder(BSL_FILE_EXTENSIONS_KEY) - .name("BSL File suffixes") - .description("List of file suffixes that will be scanned.") + PropertyDefinition.builder(LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_KEY) + .name("BSL Language Server - Skip computing diagnostics on modules with parent configurations") + .description("Skip computing diagnostics according to module's support mode " + + "(if there is a parent configuration).") .category(BSL_CATEGORY) - .defaultValue(BSL_FILE_EXTENSIONS_DEFAULT_VALUE) + .defaultValue(LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_DEFAULT_VALUE) + .type(PropertyType.SINGLE_SELECT_LIST) + .options(Stream.of(SkipSupport.values()) + .map(value -> value.name().toLowerCase(Locale.ENGLISH).replace("_", " ")) + .collect(Collectors.toList()) + ) .onQualifiers(Qualifiers.PROJECT) - .multiValues(true) .index(2) .build(), - PropertyDefinition.builder(BSL_CALCULATE_LINE_TO_COVER_KEY) - .name("BSL calculate lines to cover") - .description("Calculate lines to cover on analise") - .defaultValue(BSL_CALCULATE_LINE_TO_COVER_VALUE.toString()) - .type(PropertyType.BOOLEAN) + PropertyDefinition.builder(LANG_SERVER_OVERRIDE_CONFIGURATION_KEY) + .name("BSL Language Server - Use configuration file") + .description("Override SonarQube settings with BSL LS configuration file.") .category(BSL_CATEGORY) + .defaultValue(LANG_SERVER_OVERRIDE_CONFIGURATION_DEFAULT_VALUE.toString()) + .type(PropertyType.BOOLEAN) .onQualifiers(Qualifiers.PROJECT) .index(3) .build(), + PropertyDefinition.builder(LANG_SERVER_CONFIGURATION_PATH_KEY) + .name("BSL Language Server - Configuration file") + .description("Path to BSL LS configuration file.") + .category(BSL_CATEGORY) + .defaultValue(LANG_SERVER_CONFIGURATION_PATH_DEFAULT_VALUE) + .type(PropertyType.STRING) + .onQualifiers(Qualifiers.PROJECT) + .index(4) + .build(), + PropertyDefinition.builder(BSL_FILE_EXTENSIONS_KEY) + .name("BSL File suffixes") + .description("List of file suffixes that will be scanned.") + .category(BSL_CATEGORY) + .defaultValue(BSL_FILE_EXTENSIONS_DEFAULT_VALUE) + .onQualifiers(Qualifiers.PROJECT) + .multiValues(true) + .index(5) + .build(), PropertyDefinition.builder(LANG_SERVER_REPORT_PATH_KEY) .name("BSL Language Server Report Files") .description("Paths (absolute or relative) to xml files with BSL Language Server diagnostics") @@ -100,6 +134,7 @@ public static List getProperties() { .subCategory(BSL_SUBCATEGORY) .onQualifiers(Qualifiers.PROJECT) .multiValues(true) + .index(0) .build() ); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensor.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensor.java index 66e61e0d..5acbca94 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensor.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,23 +21,25 @@ */ package com.github._1c_syntax.bsl.sonar; -import com.github._1c_syntax.bsl.languageserver.configuration.DiagnosticLanguage; +import com.github._1c_syntax.bsl.languageserver.BSLLSBinding; +import com.github._1c_syntax.bsl.languageserver.configuration.Language; import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; +import com.github._1c_syntax.bsl.languageserver.configuration.diagnostics.SkipSupport; import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.context.MetricStorage; import com.github._1c_syntax.bsl.languageserver.context.ServerContext; -import com.github._1c_syntax.bsl.languageserver.diagnostics.BSLDiagnostic; -import com.github._1c_syntax.bsl.languageserver.diagnostics.DiagnosticSupplier; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticInfo; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameterInfo; -import com.github._1c_syntax.bsl.languageserver.providers.DiagnosticProvider; import com.github._1c_syntax.bsl.parser.BSLLexer; import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; +import com.github._1c_syntax.utils.Absolute; import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; import org.antlr.v4.runtime.Token; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; @@ -47,10 +49,6 @@ import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; -import org.sonar.api.batch.sensor.coverage.NewCoverage; -import org.sonar.api.batch.sensor.cpd.NewCpdTokens; -import org.sonar.api.batch.sensor.highlighting.NewHighlighting; -import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.FileLinesContext; import org.sonar.api.measures.FileLinesContextFactory; @@ -58,15 +56,20 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; -import javax.annotation.Nullable; +import java.io.File; import java.io.IOException; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.ArrayList; import java.util.Locale; import java.util.Map; +import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class BSLCoreSensor implements Sensor { @@ -76,11 +79,9 @@ public class BSLCoreSensor implements Sensor { private final FileLinesContextFactory fileLinesContextFactory; private final boolean langServerEnabled; - private final ServerContext bslServerContext; - private final DiagnosticProvider diagnosticProvider; + private final List sourcesList = new ArrayList<>(); private final IssuesLoader issuesLoader; - - private boolean calculateCoverLoc; + private final BSLHighlighter highlighter; public BSLCoreSensor(SensorContext context, FileLinesContextFactory fileLinesContextFactory) { this.context = context; @@ -89,13 +90,22 @@ public BSLCoreSensor(SensorContext context, FileLinesContextFactory fileLinesCon langServerEnabled = context.config().getBoolean(BSLCommunityProperties.LANG_SERVER_ENABLED_KEY) .orElse(BSLCommunityProperties.LANG_SERVER_ENABLED_DEFAULT_VALUE); - calculateCoverLoc = context.config().getBoolean(BSLCommunityProperties.BSL_CALCULATE_LINE_TO_COVER_KEY) - .orElse(BSLCommunityProperties.BSL_CALCULATE_LINE_TO_COVER_VALUE); + sourcesList.addAll(context.config().get("sonar.sources") + .map(sources -> + Arrays.stream(StringUtils.split(sources, ",")) + .map(String::strip) + .collect(Collectors.toList())) + .orElse(Collections.singletonList("."))); + + sourcesList.addAll(context.config().get("sonar.tests") + .map(sources -> + Arrays.stream(StringUtils.split(sources, ",")) + .map(String::strip) + .collect(Collectors.toList())) + .orElse(Collections.emptyList())); - bslServerContext = new ServerContext(); - DiagnosticSupplier diagnosticSupplier = new DiagnosticSupplier(getLanguageServerConfiguration()); - diagnosticProvider = new DiagnosticProvider(diagnosticSupplier); issuesLoader = new IssuesLoader(context); + highlighter = new BSLHighlighter(context); } @Override @@ -109,30 +119,70 @@ public void execute(SensorContext context) { LOGGER.info("Parsing files..."); FileSystem fileSystem = context.fileSystem(); + File baseDir = fileSystem.baseDir(); + + var absoluteSourceDirs = sourcesList.stream() + .map((String sourceDir) -> { + Path sourcePath = Path.of(sourceDir.trim()); + if (sourcePath.isAbsolute()) { + return sourcePath; + } else { + return Path.of(baseDir.toString(), sourceDir); + } + }) + .map(Absolute::path) + .collect(Collectors.toList()); + FilePredicates predicates = fileSystem.predicates(); Iterable inputFiles = fileSystem.inputFiles( - predicates.and( - predicates.hasLanguage(BSLLanguage.KEY) - ) + predicates.hasLanguage(BSLLanguage.KEY) ); - long inputFleSize = StreamSupport.stream(inputFiles.spliterator(), false).count(); + Map> inputFilesByPath = StreamSupport.stream(inputFiles.spliterator(), true) + .collect(Collectors.groupingBy((InputFile inputFile) -> { + var filePath = Absolute.path(inputFile.uri()); + return absoluteSourceDirs.stream() + .filter(filePath::startsWith) + .findAny() + .orElse(baseDir.toPath()); + })); + + LanguageServerConfiguration languageServerConfiguration = getLanguageServerConfiguration(); + + inputFilesByPath.forEach((Path sourceDir, List inputFilesList) -> { + LOGGER.info("Source dir: {}", sourceDir); + + Path configurationRoot = LanguageServerConfiguration.getCustomConfigurationRoot( + languageServerConfiguration, + sourceDir + ); - try (ProgressBar pb = new ProgressBar("", inputFleSize, ProgressBarStyle.ASCII)) { - StreamSupport.stream(inputFiles.spliterator(), true) - .forEach((InputFile inputFile) -> { + var bslServerContext = BSLLSBinding.getServerContext(); + bslServerContext.setConfigurationRoot(configurationRoot); + bslServerContext.populateContext(); + + try (ProgressBar pb = new ProgressBarBuilder() + .setTaskName("") + .setInitialMax(inputFilesList.size()) + .setStyle(ProgressBarStyle.ASCII) + .build()) { + inputFilesList.parallelStream().forEach((InputFile inputFile) -> { URI uri = inputFile.uri(); LOGGER.debug(uri.toString()); pb.step(); - processFile(inputFile); + processFile(inputFile, bslServerContext); }); - } + } + bslServerContext.clear(); + }); + + BSLLSBinding.getApplicationContext().close(); } - private void processFile(InputFile inputFile) { + private void processFile(InputFile inputFile, ServerContext bslServerContext) { URI uri = inputFile.uri(); String content; @@ -142,75 +192,53 @@ private void processFile(InputFile inputFile) { LOGGER.warn("Can't read content of file " + uri, e); content = ""; } - DocumentContext documentContext = bslServerContext.addDocument(uri, content); + DocumentContext documentContext = bslServerContext.addDocument(uri, content, 1); if (langServerEnabled) { - diagnosticProvider.computeDiagnostics(documentContext) + documentContext.getDiagnostics() .forEach(diagnostic -> issuesLoader.createIssue(inputFile, diagnostic)); - diagnosticProvider.clearComputedDiagnostics(documentContext); } saveCpd(inputFile, documentContext); - saveHighlighting(inputFile, documentContext); + highlighter.saveHighlighting(inputFile, documentContext); saveMeasures(inputFile, documentContext); - saveCoverageLoc(inputFile, documentContext); - - documentContext.clearASTData(); + documentContext.clearSecondaryData(); } private void saveCpd(InputFile inputFile, DocumentContext documentContext) { - NewCpdTokens cpdTokens = context.newCpdTokens(); + var cpdTokens = context.newCpdTokens(); cpdTokens.onFile(inputFile); - documentContext.getTokensFromDefaultChannel() - .forEach((Token token) -> { - int line = token.getLine(); - int charPositionInLine = token.getCharPositionInLine(); - String tokenText = token.getText(); - cpdTokens.addToken( - line, - charPositionInLine, - line, - charPositionInLine + tokenText.length(), - tokenText - ); - } - ); - - synchronized (this) { - cpdTokens.save(); - } - - } - - private void saveHighlighting(InputFile inputFile, DocumentContext documentContext) { - - NewHighlighting highlighting = context.newHighlighting().onFile(inputFile); - - documentContext.getTokens().forEach((Token token) -> { - TypeOfText typeOfText = getTypeOfText(token.getType()); + var skipCpd = false; + for (Token token : documentContext.getTokens()) { + if (token.getChannel() != Token.DEFAULT_CHANNEL) { + skipCpd = checkSkipCpd(token, skipCpd); + continue; + } - if (typeOfText == null) { - return; + if (!skipCpd) { + int line = token.getLine(); + int charPositionInLine = token.getCharPositionInLine(); + String tokenText = token.getText(); + cpdTokens.addToken( + line, + charPositionInLine, + line, + charPositionInLine + tokenText.length(), + tokenText + ); } - int line = token.getLine(); - int charPositionInLine = token.getCharPositionInLine(); - String tokenText = token.getText(); + skipCpd = checkSkipCpd(token, skipCpd); - highlighting.highlight( - line, - charPositionInLine, - line, - charPositionInLine + tokenText.length(), - typeOfText - ); - }); + } - highlighting.save(); + synchronized (this) { + cpdTokens.save(); + } } @@ -240,6 +268,12 @@ private void saveMeasures(InputFile inputFile, DocumentContext documentContext) .withValue(metrics.getCognitiveComplexity()) .save(); + context.newMeasure() + .on(inputFile) + .forMetric(CoreMetrics.COMPLEXITY) + .withValue(metrics.getCyclomaticComplexity()) + .save(); + context.newMeasure() .on(inputFile) .forMetric(CoreMetrics.COMMENT_LINES) @@ -254,46 +288,62 @@ private void saveMeasures(InputFile inputFile, DocumentContext documentContext) } - private void saveCoverageLoc(InputFile inputFile, DocumentContext documentContext) { + private LanguageServerConfiguration getLanguageServerConfiguration() { - if (!calculateCoverLoc) { - return; + boolean overrideConfiguration = context.config() + .get(BSLCommunityProperties.LANG_SERVER_OVERRIDE_CONFIGURATION_KEY) + .map(Boolean::parseBoolean) + .orElse(BSLCommunityProperties.LANG_SERVER_OVERRIDE_CONFIGURATION_DEFAULT_VALUE); + + var configuration = BSLLSBinding.getLanguageServerConfiguration(); + if (overrideConfiguration) { + String configurationPath = context.config() + .get(BSLCommunityProperties.LANG_SERVER_CONFIGURATION_PATH_KEY) + .orElse(BSLCommunityProperties.LANG_SERVER_CONFIGURATION_PATH_DEFAULT_VALUE); + + File configurationFile = new File(configurationPath); + if (configurationFile.exists()) { + LOGGER.info("BSL LS configuration file exists. Overriding SonarQube rules' settings..."); + configuration.update(configurationFile); + return configuration; + } else { + LOGGER.error("Can't find bsl configuration file {}. Using SonarQube config instead.", configurationPath); + } } - NewCoverage coverage = context.newCoverage().onFile(inputFile); - - Arrays.stream(documentContext.getMetrics().getCovlocData()) - .forEach(loc -> coverage.lineHits(loc, 0)); - - coverage.save(); - - } - - private LanguageServerConfiguration getLanguageServerConfiguration() { - LanguageServerConfiguration languageServerConfiguration = LanguageServerConfiguration.create(); String diagnosticLanguageCode = context.config() .get(BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_KEY) .orElse(BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_DEFAULT_VALUE); - languageServerConfiguration.setDiagnosticLanguage( - DiagnosticLanguage.valueOf(diagnosticLanguageCode.toUpperCase(Locale.ENGLISH)) + configuration.setLanguage( + Language.valueOf(diagnosticLanguageCode.toUpperCase(Locale.ENGLISH)) ); + SkipSupport skipSupport = context.config() + .get(BSLCommunityProperties.LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_KEY) + .map(value -> value.toUpperCase(Locale.ENGLISH).replace(" ", "_")) + .map(SkipSupport::valueOf) + .orElse(SkipSupport.valueOf( + BSLCommunityProperties.LANG_SERVER_COMPUTE_DIAGNOSTICS_SKIP_SUPPORT_DEFAULT_VALUE.toUpperCase(Locale.ENGLISH) + )); + + configuration.getDiagnosticsOptions().setSkipSupport(skipSupport); + ActiveRules activeRules = context.activeRules(); Map>> diagnostics = new HashMap<>(); - List> diagnosticClasses = DiagnosticSupplier.getDiagnosticClasses(); + Collection diagnosticInfos = BSLLSBinding.getDiagnosticInfos(); - for (Class diagnosticClass : diagnosticClasses) { - DiagnosticInfo diagnosticInfo = new DiagnosticInfo(diagnosticClass); + for (DiagnosticInfo diagnosticInfo : diagnosticInfos) { + String diagnosticCode = diagnosticInfo.getCode().getStringValue(); ActiveRule activeRule = activeRules.find( RuleKey.of( BSLLanguageServerRuleDefinition.REPOSITORY_KEY, - diagnosticInfo.getCode() + diagnosticCode ) ); if (activeRule == null) { - diagnostics.put(diagnosticInfo.getCode(), Either.forLeft(false)); + diagnostics.put(diagnosticCode, Either.forLeft(false)); } else { Map params = activeRule.params(); @@ -309,108 +359,18 @@ private LanguageServerConfiguration getLanguageServerConfiguration() { ) ); diagnostics.put( - diagnosticInfo.getCode(), + diagnosticCode, Either.forRight(diagnosticConfiguration) ); } } - languageServerConfiguration.setDiagnostics(diagnostics); - - return languageServerConfiguration; - } - - @Nullable - private static TypeOfText getTypeOfText(int tokenType) { - - TypeOfText typeOfText = null; - - switch (tokenType) { - case BSLLexer.PROCEDURE_KEYWORD: - case BSLLexer.FUNCTION_KEYWORD: - case BSLLexer.ENDPROCEDURE_KEYWORD: - case BSLLexer.ENDFUNCTION_KEYWORD: - case BSLLexer.EXPORT_KEYWORD: - case BSLLexer.VAL_KEYWORD: - case BSLLexer.ENDIF_KEYWORD: - case BSLLexer.ENDDO_KEYWORD: - case BSLLexer.IF_KEYWORD: - case BSLLexer.ELSIF_KEYWORD: - case BSLLexer.ELSE_KEYWORD: - case BSLLexer.THEN_KEYWORD: - case BSLLexer.WHILE_KEYWORD: - case BSLLexer.DO_KEYWORD: - case BSLLexer.FOR_KEYWORD: - case BSLLexer.TO_KEYWORD: - case BSLLexer.EACH_KEYWORD: - case BSLLexer.IN_KEYWORD: - case BSLLexer.TRY_KEYWORD: - case BSLLexer.EXCEPT_KEYWORD: - case BSLLexer.ENDTRY_KEYWORD: - case BSLLexer.RETURN_KEYWORD: - case BSLLexer.CONTINUE_KEYWORD: - case BSLLexer.RAISE_KEYWORD: - case BSLLexer.VAR_KEYWORD: - case BSLLexer.NOT_KEYWORD: - case BSLLexer.OR_KEYWORD: - case BSLLexer.AND_KEYWORD: - case BSLLexer.NEW_KEYWORD: - case BSLLexer.GOTO_KEYWORD: - case BSLLexer.BREAK_KEYWORD: - case BSLLexer.EXECUTE_KEYWORD: - typeOfText = TypeOfText.KEYWORD; - break; - case BSLLexer.TRUE: - case BSLLexer.FALSE: - case BSLLexer.UNDEFINED: - case BSLLexer.NULL: - case BSLLexer.DATETIME: - case BSLLexer.DECIMAL: - case BSLLexer.FLOAT: - typeOfText = TypeOfText.CONSTANT; - break; - case BSLLexer.STRING: - case BSLLexer.STRINGSTART: - case BSLLexer.STRINGPART: - case BSLLexer.STRINGTAIL: - case BSLLexer.PREPROC_STRING: - typeOfText = TypeOfText.STRING; - break; - case BSLLexer.LINE_COMMENT: - typeOfText = TypeOfText.COMMENT; - break; - case BSLLexer.HASH: - case BSLLexer.PREPROC_USE_KEYWORD: - case BSLLexer.PREPROC_REGION: - case BSLLexer.PREPROC_END_REGION: - case BSLLexer.PREPROC_AND_KEYWORD: - case BSLLexer.PREPROC_OR_KEYWORD: - case BSLLexer.PREPROC_NOT_KEYWORD: - case BSLLexer.PREPROC_IF_KEYWORD: - case BSLLexer.PREPROC_THEN_KEYWORD: - case BSLLexer.PREPROC_ELSIF_KEYWORD: - case BSLLexer.PREPROC_ELSE_KEYWORD: - case BSLLexer.PREPROC_ENDIF_KEYWORD: - typeOfText = TypeOfText.PREPROCESS_DIRECTIVE; - break; - case BSLLexer.AMPERSAND: - case BSLLexer.ANNOTATION_ATCLIENT_SYMBOL: - case BSLLexer.ANNOTATION_ATCLIENTATSERVER_SYMBOL: - case BSLLexer.ANNOTATION_ATCLIENTATSERVERNOCONTEXT_SYMBOL: - case BSLLexer.ANNOTATION_ATSERVER_SYMBOL: - case BSLLexer.ANNOTATION_ATSERVERNOCONTEXT_SYMBOL: - case BSLLexer.ANNOTATION_CUSTOM_SYMBOL: - typeOfText = TypeOfText.ANNOTATION; - break; - default: - // no-op - } - - return typeOfText; + configuration.getDiagnosticsOptions().setParameters(diagnostics); + return configuration; } - private static Object castDiagnosticParameterValue(String valueToCast, Class type) { + private static Object castDiagnosticParameterValue(String valueToCast, Class type) { Object value; if (type == Integer.class) { value = Integer.parseInt(valueToCast); @@ -427,4 +387,19 @@ private static Object castDiagnosticParameterValue(String valueToCast, Class typ return value; } + private static boolean checkSkipCpd(Token token, boolean skipCpd) { + int tokenType = token.getType(); + if (tokenType == BSLLexer.ANNOTATION_CHANGEANDVALIDATE_SYMBOL + || tokenType == BSLLexer.PREPROC_ENDINSERT) { + skipCpd = true; + } + + if (tokenType == BSLLexer.ENDPROCEDURE_KEYWORD + || tokenType == BSLLexer.ENDFUNCTION_KEYWORD + || tokenType == BSLLexer.PREPROC_INSERT) { + skipCpd = false; + } + return skipCpd; + } + } diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighter.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighter.java new file mode 100644 index 00000000..3bb5856f --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighter.java @@ -0,0 +1,627 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.utils.Ranges; +import com.github._1c_syntax.bsl.parser.BSLLexer; +import com.github._1c_syntax.bsl.parser.SDBLLexer; +import com.github._1c_syntax.bsl.parser.Tokenizer; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; +import org.antlr.v4.runtime.Token; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.highlighting.NewHighlighting; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public class BSLHighlighter { + + private static final Set BSL_KEYWORDS = createBslKeywords(); + private static final Set BSL_SEPARATORS = createBslSeparators(); + private static final Set BSL_LITERALS = createBslLiterals(); + private static final Set BSL_STRINGS = createBslStrings(); + private static final Set BSL_COMMENTS = createBslComments(); + private static final Set BSL_PREPROCESSOR = createBslPreprocessor(); + private static final Set BSL_ANNOTATIONS = createBslAnnotations(); + + private static final Set SDBL_KEYWORDS = createSdblKeywords(); + private static final Set SDBL_FUNCTIONS = createSdblFunctions(); + private static final Set SDBL_METADATA_TYPES = createSdblMetadataTypes(); + private static final Set SDBL_VIRTUAL_TABLES = createSdblVirtualTables(); + private static final Set SDBL_LITERALS = createSdblLiterals(); + private static final Set SDBL_SEPARATORS = createSdblSeparators(); + private static final Set SDBL_STRINGS = createSdblStrings(); + private static final Set SDBL_COMMENTS = createSdblComments(); + private static final Set SDBL_PARAMETERS = createSdblParameters(); + + private final SensorContext context; + + public void saveHighlighting(InputFile inputFile, DocumentContext documentContext) { + Set highlightingData = new HashSet<>(documentContext.getTokens().size()); + + // populate bsl highlight data + documentContext.getTokens().forEach(token -> + highlightToken(token, highlightingData, getTypeOfTextBSL(token.getType())) + ); + + // compute and populate sdbl highlight data + Map> queryTokens = documentContext.getQueries().stream() + .map(Tokenizer::getTokens) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(Token::getLine)); + Map> highlightingDataSDBL = new HashMap<>(queryTokens.size()); + + queryTokens.values().stream() + .flatMap(Collection::stream) + .forEach(token -> highlightToken( + token, + highlightingDataSDBL.computeIfAbsent(token.getLine(), BSLHighlighter::newHashSet), + getTypeOfTextSDBL(token.getType())) + ); + + // find bsl strings to check overlap with sdbl tokens + Set strings = highlightingData.stream() + .filter(data -> data.getType() == TypeOfText.STRING) + .collect(Collectors.toSet()); + + strings.forEach((HighlightingData string) -> { + Range stringRange = string.getRange(); + + // find overlapping tokens + Set dataOfCurrentLine = highlightingDataSDBL.get(stringRange.getStart().getLine()); + if (Objects.isNull(dataOfCurrentLine)) { + return; + } + + List currentTokens = dataOfCurrentLine.stream() + .filter(sdblData -> Ranges.containsRange(stringRange, sdblData.getRange())) + .sorted(Comparator.comparing(data -> data.getRange().getStart().getCharacter())) + .collect(Collectors.toList()); + + if (currentTokens.isEmpty()) { + return; + } + + // disable current bsl token + string.setActive(false); + + // split current bsl token to parts excluding sdbl tokens + Position start = stringRange.getStart(); + int line = start.getLine(); + int startChar; + int endChar = start.getCharacter(); + for (HighlightingData currentToken : currentTokens) { + startChar = endChar; + endChar = currentToken.getRange().getStart().getCharacter(); + TypeOfText typeOfText = string.getType(); + + if (startChar < endChar) { + // add string part + highlightingData.add(new HighlightingData( + line, + startChar, + endChar, + typeOfText + )); + } + + endChar = currentToken.getRange().getEnd().getCharacter(); + } + + // add final string part + startChar = endChar; + endChar = string.getRange().getEnd().getCharacter(); + TypeOfText typeOfText = string.getType(); + + if (startChar < endChar) { + highlightingData.add(new HighlightingData( + line, + startChar, + endChar, + typeOfText + )); + } + }); + + // merge collected bsl tokens with sdbl tokens + highlightingDataSDBL.values().forEach(highlightingData::addAll); + + if (highlightingData.stream() + .filter(HighlightingData::isActive) + .findAny() + .isEmpty()) { + return; + } + + // save only active tokens + NewHighlighting highlighting = context.newHighlighting().onFile(inputFile); + + highlightingData.stream() + .filter(HighlightingData::isActive) + .forEach(data -> + highlighting.highlight( + data.getRange().getStart().getLine(), + data.getRange().getStart().getCharacter(), + data.getRange().getEnd().getLine(), + data.getRange().getEnd().getCharacter(), + data.getType() + ) + ); + + highlighting.save(); + } + + public void highlightToken( + Token token, + Collection highlightingData, + @Nullable TypeOfText typeOfText + ) { + if (typeOfText == null) { + return; + } + + int line = token.getLine(); + int charPositionInLine = token.getCharPositionInLine(); + String tokenText = token.getText(); + + Range range = Ranges.create( + line, + charPositionInLine, + line, + charPositionInLine + tokenText.length() + ); + + HighlightingData data = new HighlightingData( + range, + typeOfText + ); + + highlightingData.add(data); + } + + @Nullable + private static TypeOfText getTypeOfTextBSL(int tokenType) { + TypeOfText typeOfText; + + if (BSL_KEYWORDS.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD; + } else if (BSL_SEPARATORS.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (BSL_LITERALS.contains(tokenType)) { + typeOfText = TypeOfText.CONSTANT; + } else if (BSL_STRINGS.contains(tokenType)) { + typeOfText = TypeOfText.STRING; + } else if (BSL_COMMENTS.contains(tokenType)) { + typeOfText = TypeOfText.COMMENT; + } else if (BSL_PREPROCESSOR.contains(tokenType)) { + typeOfText = TypeOfText.PREPROCESS_DIRECTIVE; + } else if (BSL_ANNOTATIONS.contains(tokenType)) { + typeOfText = TypeOfText.ANNOTATION; + } else { + typeOfText = null; + } + + return typeOfText; + } + + @Nullable + private static TypeOfText getTypeOfTextSDBL(int tokenType) { + TypeOfText typeOfText; + + if (SDBL_KEYWORDS.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD; + } else if (SDBL_FUNCTIONS.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (SDBL_METADATA_TYPES.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (SDBL_VIRTUAL_TABLES.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (SDBL_LITERALS.contains(tokenType)) { + typeOfText = TypeOfText.CONSTANT; + } else if (SDBL_SEPARATORS.contains(tokenType)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (SDBL_STRINGS.contains(tokenType)) { + typeOfText = TypeOfText.STRING; + } else if (SDBL_COMMENTS.contains(tokenType)) { + typeOfText = TypeOfText.COMMENT; + } else if (SDBL_PARAMETERS.contains(tokenType)) { + typeOfText = TypeOfText.ANNOTATION; + } else { + typeOfText = null; + } + + return typeOfText; + } + + private static Set newHashSet(Integer line) { + return new HashSet<>(); + } + + private static Set createBslAnnotations() { + return Set.of( + BSLLexer.AMPERSAND, + BSLLexer.ANNOTATION_AFTER_SYMBOL, + BSLLexer.ANNOTATION_AROUND_SYMBOL, + BSLLexer.ANNOTATION_ATCLIENT_SYMBOL, + BSLLexer.ANNOTATION_ATCLIENTATSERVER_SYMBOL, + BSLLexer.ANNOTATION_ATCLIENTATSERVERNOCONTEXT_SYMBOL, + BSLLexer.ANNOTATION_ATSERVER_SYMBOL, + BSLLexer.ANNOTATION_ATSERVERNOCONTEXT_SYMBOL, + BSLLexer.ANNOTATION_BEFORE_SYMBOL, + BSLLexer.ANNOTATION_CHANGEANDVALIDATE_SYMBOL, + BSLLexer.ANNOTATION_CUSTOM_SYMBOL, + BSLLexer.ANNOTATION_UNKNOWN + ); + } + + private static Set createBslPreprocessor() { + return Set.of( + BSLLexer.HASH, + BSLLexer.PREPROC_USE_KEYWORD, + BSLLexer.PREPROC_REGION, + BSLLexer.PREPROC_END_REGION, + BSLLexer.PREPROC_AND_KEYWORD, + BSLLexer.PREPROC_OR_KEYWORD, + BSLLexer.PREPROC_NOT_KEYWORD, + BSLLexer.PREPROC_IF_KEYWORD, + BSLLexer.PREPROC_THEN_KEYWORD, + BSLLexer.PREPROC_ELSIF_KEYWORD, + BSLLexer.PREPROC_ELSE_KEYWORD, + BSLLexer.PREPROC_ENDIF_KEYWORD, + BSLLexer.PREPROC_EXCLAMATION_MARK, + BSLLexer.PREPROC_LPAREN, + BSLLexer.PREPROC_RPAREN, + BSLLexer.PREPROC_MOBILEAPPCLIENT_SYMBOL, + BSLLexer.PREPROC_MOBILEAPPSERVER_SYMBOL, + BSLLexer.PREPROC_MOBILECLIENT_SYMBOL, + BSLLexer.PREPROC_THICKCLIENTORDINARYAPPLICATION_SYMBOL, + BSLLexer.PREPROC_THICKCLIENTMANAGEDAPPLICATION_SYMBOL, + BSLLexer.PREPROC_EXTERNALCONNECTION_SYMBOL, + BSLLexer.PREPROC_THINCLIENT_SYMBOL, + BSLLexer.PREPROC_WEBCLIENT_SYMBOL, + BSLLexer.PREPROC_ATCLIENT_SYMBOL, + BSLLexer.PREPROC_CLIENT_SYMBOL, + BSLLexer.PREPROC_ATSERVER_SYMBOL, + BSLLexer.PREPROC_SERVER_SYMBOL, + BSLLexer.PREPROC_INSERT, + BSLLexer.PREPROC_ENDINSERT, + BSLLexer.PREPROC_DELETE, + BSLLexer.PREPROC_DELETE_ANY, + BSLLexer.PREPROC_ENDDELETE, + BSLLexer.PREPROC_IDENTIFIER, + BSLLexer.PREPROC_LINUX, + BSLLexer.PREPROC_WINDOWS, + BSLLexer.PREPROC_MACOS, + BSLLexer.PREPROC_ANY, + BSLLexer.PREPROC_MOBILE_STANDALONE_SERVER + ); + } + + private static Set createBslComments() { + return Set.of( + BSLLexer.LINE_COMMENT + ); + } + + private static Set createBslStrings() { + return Set.of( + BSLLexer.STRING, + BSLLexer.STRINGSTART, + BSLLexer.STRINGPART, + BSLLexer.STRINGTAIL, + BSLLexer.PREPROC_STRING + ); + } + + private static Set createBslLiterals() { + return Set.of( + BSLLexer.TRUE, + BSLLexer.FALSE, + BSLLexer.UNDEFINED, + BSLLexer.NULL, + BSLLexer.DATETIME, + BSLLexer.DECIMAL, + BSLLexer.FLOAT + ); + } + + private static Set createBslSeparators() { + return Set.of( + BSLLexer.SEMICOLON, + BSLLexer.QUESTION, + BSLLexer.PLUS, + BSLLexer.MINUS, + BSLLexer.MUL, + BSLLexer.QUOTIENT, + BSLLexer.MODULO, + BSLLexer.ASSIGN, + BSLLexer.LESS_OR_EQUAL, + BSLLexer.LESS, + BSLLexer.NOT_EQUAL, + BSLLexer.GREATER_OR_EQUAL, + BSLLexer.GREATER, + BSLLexer.COMMA, + BSLLexer.COLON, + BSLLexer.TILDA + ); + } + + private static Set createBslKeywords() { + return Set.of( + BSLLexer.PROCEDURE_KEYWORD, + BSLLexer.FUNCTION_KEYWORD, + BSLLexer.ENDPROCEDURE_KEYWORD, + BSLLexer.ENDFUNCTION_KEYWORD, + BSLLexer.EXPORT_KEYWORD, + BSLLexer.VAL_KEYWORD, + BSLLexer.ENDIF_KEYWORD, + BSLLexer.ENDDO_KEYWORD, + BSLLexer.IF_KEYWORD, + BSLLexer.ELSIF_KEYWORD, + BSLLexer.ELSE_KEYWORD, + BSLLexer.THEN_KEYWORD, + BSLLexer.WHILE_KEYWORD, + BSLLexer.DO_KEYWORD, + BSLLexer.FOR_KEYWORD, + BSLLexer.TO_KEYWORD, + BSLLexer.EACH_KEYWORD, + BSLLexer.IN_KEYWORD, + BSLLexer.TRY_KEYWORD, + BSLLexer.EXCEPT_KEYWORD, + BSLLexer.ENDTRY_KEYWORD, + BSLLexer.RETURN_KEYWORD, + BSLLexer.CONTINUE_KEYWORD, + BSLLexer.RAISE_KEYWORD, + BSLLexer.VAR_KEYWORD, + BSLLexer.NOT_KEYWORD, + BSLLexer.OR_KEYWORD, + BSLLexer.AND_KEYWORD, + BSLLexer.NEW_KEYWORD, + BSLLexer.GOTO_KEYWORD, + BSLLexer.BREAK_KEYWORD, + BSLLexer.EXECUTE_KEYWORD, + BSLLexer.ADDHANDLER_KEYWORD, + BSLLexer.REMOVEHANDLER_KEYWORD, + BSLLexer.ASYNC_KEYWORD, + BSLLexer.AWAIT_KEYWORD + ); + } + + private static Set createSdblSeparators() { + return Set.of( + SDBLLexer.SEMICOLON, + SDBLLexer.PLUS, + SDBLLexer.MINUS, + SDBLLexer.MUL, + SDBLLexer.QUOTIENT, + SDBLLexer.ASSIGN, + SDBLLexer.LESS_OR_EQUAL, + SDBLLexer.LESS, + SDBLLexer.NOT_EQUAL, + SDBLLexer.GREATER_OR_EQUAL, + SDBLLexer.GREATER, + SDBLLexer.COMMA, + SDBLLexer.BRACE, + SDBLLexer.BRACE_START + ); + } + + private static Set createSdblLiterals() { + return Set.of( + SDBLLexer.TRUE, + SDBLLexer.FALSE, + SDBLLexer.UNDEFINED, + SDBLLexer.NULL, + SDBLLexer.DECIMAL, + SDBLLexer.FLOAT + ); + } + + private static Set createSdblVirtualTables() { + return Set.of( + SDBLLexer.ACTUAL_ACTION_PERIOD_VT, + SDBLLexer.BALANCE_VT, + SDBLLexer.BALANCE_AND_TURNOVERS_VT, + SDBLLexer.BOUNDARIES_VT, + SDBLLexer.DR_CR_TURNOVERS_VT, + SDBLLexer.EXT_DIMENSIONS_VT, + SDBLLexer.RECORDS_WITH_EXT_DIMENSIONS_VT, + SDBLLexer.SCHEDULE_DATA_VT, + SDBLLexer.SLICEFIRST_VT, + SDBLLexer.SLICELAST_VT, + SDBLLexer.TASK_BY_PERFORMER_VT, + SDBLLexer.TURNOVERS_VT + ); + } + + private static Set createSdblMetadataTypes() { + return Set.of( + SDBLLexer.ACCOUNTING_REGISTER_TYPE, + SDBLLexer.ACCUMULATION_REGISTER_TYPE, + SDBLLexer.BUSINESS_PROCESS_TYPE, + SDBLLexer.CALCULATION_REGISTER_TYPE, + SDBLLexer.CATALOG_TYPE, + SDBLLexer.CHART_OF_ACCOUNTS_TYPE, + SDBLLexer.CHART_OF_CALCULATION_TYPES_TYPE, + SDBLLexer.CHART_OF_CHARACTERISTIC_TYPES_TYPE, + SDBLLexer.CONSTANT_TYPE, + SDBLLexer.DOCUMENT_TYPE, + SDBLLexer.DOCUMENT_JOURNAL_TYPE, + SDBLLexer.ENUM_TYPE, + SDBLLexer.EXCHANGE_PLAN_TYPE, + SDBLLexer.EXTERNAL_DATA_SOURCE_TYPE, + SDBLLexer.FILTER_CRITERION_TYPE, + SDBLLexer.INFORMATION_REGISTER_TYPE, + SDBLLexer.SEQUENCE_TYPE, + SDBLLexer.TASK_TYPE + ); + } + + private static Set createSdblFunctions() { + return Set.of( + SDBLLexer.AVG, + SDBLLexer.BEGINOFPERIOD, + SDBLLexer.BOOLEAN, + SDBLLexer.COUNT, + SDBLLexer.DATE, + SDBLLexer.DATEADD, + SDBLLexer.DATEDIFF, + SDBLLexer.DATETIME, + SDBLLexer.DAY, + SDBLLexer.DAYOFYEAR, + SDBLLexer.EMPTYTABLE, + SDBLLexer.ENDOFPERIOD, + SDBLLexer.HALFYEAR, + SDBLLexer.HOUR, + SDBLLexer.MAX, + SDBLLexer.MIN, + SDBLLexer.MINUTE, + SDBLLexer.MONTH, + SDBLLexer.NUMBER, + SDBLLexer.QUARTER, + SDBLLexer.PRESENTATION, + SDBLLexer.RECORDAUTONUMBER, + SDBLLexer.REFPRESENTATION, + SDBLLexer.SECOND, + SDBLLexer.STRING, + SDBLLexer.SUBSTRING, + SDBLLexer.SUM, + SDBLLexer.TENDAYS, + SDBLLexer.TYPE, + SDBLLexer.VALUE, + SDBLLexer.VALUETYPE, + SDBLLexer.WEEK, + SDBLLexer.WEEKDAY, + SDBLLexer.YEAR + ); + } + + private static Set createSdblKeywords() { + return Set.of( + SDBLLexer.ALL, + SDBLLexer.ALLOWED, + SDBLLexer.AND, + SDBLLexer.AS, + SDBLLexer.ASC, + SDBLLexer.AUTOORDER, + SDBLLexer.BETWEEN, + SDBLLexer.BY_EN, + SDBLLexer.CASE, + SDBLLexer.CAST, + SDBLLexer.DESC, + SDBLLexer.DISTINCT, + SDBLLexer.DROP, + SDBLLexer.ELSE, + SDBLLexer.END, + SDBLLexer.ESCAPE, + SDBLLexer.FALSE, + SDBLLexer.FOR, + SDBLLexer.FROM, + SDBLLexer.FULL, + SDBLLexer.GROUP, + SDBLLexer.HAVING, + SDBLLexer.HIERARCHY, + SDBLLexer.HIERARCHY_FOR_IN, + SDBLLexer.IN, + SDBLLexer.INDEX, + SDBLLexer.INNER, + SDBLLexer.INTO, + SDBLLexer.IS, + SDBLLexer.ISNULL, + SDBLLexer.JOIN, + SDBLLexer.LEFT, + SDBLLexer.LIKE, + SDBLLexer.NOT, + SDBLLexer.OF, + SDBLLexer.ONLY, + SDBLLexer.ON_EN, + SDBLLexer.OR, + SDBLLexer.ORDER, + SDBLLexer.OVERALL, + SDBLLexer.OUTER, + SDBLLexer.PERIODS, + SDBLLexer.PO_RU, + SDBLLexer.REFS, + SDBLLexer.RIGHT, + SDBLLexer.SELECT, + SDBLLexer.SET, + SDBLLexer.THEN, + SDBLLexer.TOP, + SDBLLexer.TOTALS, + SDBLLexer.UNION, + SDBLLexer.UPDATE, + SDBLLexer.WHEN, + SDBLLexer.WHERE, + SDBLLexer.EMPTYREF, + SDBLLexer.GROUPEDBY, + SDBLLexer.GROUPING + ); + } + + private static Set createSdblStrings() { + return Set.of( + SDBLLexer.STR + ); + } + + private static Set createSdblComments() { + return Set.of( + SDBLLexer.LINE_COMMENT + ); + } + + private static Set createSdblParameters() { + return Set.of( + SDBLLexer.AMPERSAND, + SDBLLexer.PARAMETER_IDENTIFIER + ); + } + + @Data + @RequiredArgsConstructor + @EqualsAndHashCode(exclude = "active") + private static class HighlightingData { + private final Range range; + private final TypeOfText type; + private boolean active = true; + + public HighlightingData(int line, int startChar, int endChar, TypeOfText type) { + this(Ranges.create(line, startChar, endChar), type); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLPlugin.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLPlugin.java index 2766780f..9ae1d79e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLPlugin.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/BSLPlugin.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,9 +21,12 @@ */ package com.github._1c_syntax.bsl.sonar; +import com.github._1c_syntax.bsl.sonar.ext_issues.ExternalReporters; +import com.github._1c_syntax.bsl.sonar.ext_issues.QualityProfilesContainer; +import com.github._1c_syntax.bsl.sonar.ext_issues.RuleDefinitionsContainer; import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; -import com.github._1c_syntax.bsl.sonar.language.BSLQualityProfile; import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; +import com.github._1c_syntax.bsl.sonar.language.BSLQualityProfile; import org.sonar.api.Plugin; public class BSLPlugin implements Plugin { @@ -34,10 +37,13 @@ public void define(Context context) { context.addExtension(BSLQualityProfile.class); context.addExtensions(BSLCommunityProperties.getProperties()); + ExternalReporters.REPORTERS.forEach(reporter -> reporter.addExtension(context)); context.addExtension(BSLLanguageServerRuleDefinition.class); + context.addExtension(QualityProfilesContainer.class); + context.addExtension(RuleDefinitionsContainer.class); context.addExtension(BSLCoreSensor.class); context.addExtension(LanguageServerDiagnosticsLoaderSensor.class); - } + } diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/IssuesLoader.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/IssuesLoader.java index e1ae743f..8af7a624 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/IssuesLoader.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/IssuesLoader.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,22 +21,25 @@ */ package com.github._1c_syntax.bsl.sonar; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCode; +import com.github._1c_syntax.bsl.sonar.ext_issues.ExternalReporters; +import com.github._1c_syntax.bsl.sonar.ext_issues.Reporter; import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; +import lombok.AllArgsConstructor; +import lombok.Value; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticRelatedInformation; import org.eclipse.lsp4j.DiagnosticSeverity; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; +import org.jetbrains.annotations.NotNull; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.rule.ActiveRule; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.issue.NewExternalIssue; -import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.issue.NewIssueLocation; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; @@ -50,10 +53,15 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; public class IssuesLoader { private static final Logger LOGGER = Loggers.get(IssuesLoader.class); + private static final String BSLLS_ENGINE_ID = "bsl-language-server"; private final SensorContext context; private final Map severityMap; @@ -61,177 +69,189 @@ public class IssuesLoader { private final FileSystem fileSystem; private final FilePredicates predicates; + private final Map loaderSettings; + public IssuesLoader(SensorContext context) { this.context = context; this.fileSystem = context.fileSystem(); this.predicates = fileSystem.predicates(); this.severityMap = createDiagnosticSeverityMap(); this.ruleTypeMap = createRuleTypeMap(); + + this.loaderSettings = computeLoaderSettings(context); } - public void createIssue(InputFile inputFile, Diagnostic diagnostic) { + private static TextRange getTextRange(InputFile inputFile, Range range, String ruleKey) { + Position start = range.getStart(); + Position end = range.getEnd(); + int startLine = start.getLine() + 1; - RuleKey ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnostic.getCode()); - ActiveRule activeRule = context.activeRules().find(ruleKey); - if (activeRule == null) { - createExternalIssue(inputFile, diagnostic); - return; + TextRange textRange; + + try { + textRange = inputFile.newRange(startLine, start.getCharacter(), end.getLine() + 1, end.getCharacter()); + } catch (IllegalArgumentException e) { + var formattedRange = String.format("start(%d, %d), end(%d, %d)", range.getStart().getLine(), range.getStart().getCharacter(), range.getEnd().getLine(), range.getEnd().getCharacter()); + LOGGER.error("Can't compute TextRange for given Range: {} of rule: {} in file: {}.", formattedRange, ruleKey, inputFile.uri(), e); + + textRange = selectThisOrPreviousLine(inputFile, startLine); } - NewIssue issue = context.newIssue(); + return textRange; - issue.forRule(ruleKey); + } - NewIssueLocation location = IssuesLoader.getNewIssueLocation( - issue, - inputFile, - diagnostic.getRange(), - diagnostic.getMessage() - ); - issue.at(location); + private static TextRange selectThisOrPreviousLine(InputFile inputFile, int line) { + int lines = inputFile.lines(); - List relatedInformation = diagnostic.getRelatedInformation(); - if (relatedInformation != null) { - relatedInformation.forEach( - (DiagnosticRelatedInformation relatedInformationEntry) -> { - Path path = Paths.get(URI.create(relatedInformationEntry.getLocation().getUri())).toAbsolutePath(); - InputFile relatedInputFile = getInputFile(path); - if (relatedInputFile == null) { - LOGGER.warn("Can't find inputFile for absolute path {}", path); - return; - } - - NewIssueLocation newIssueLocation = getNewIssueLocation( - issue, - relatedInputFile, - relatedInformationEntry.getLocation().getRange(), - relatedInformationEntry.getMessage() - ); - if (newIssueLocation != null) { - issue.addLocation(newIssueLocation); - } - } - ); + if (line == 0) { + return inputFile.newRange(1, 0, lines, 0); } - issue.save(); + if (lines >= line) { + try { + return inputFile.selectLine(line); + } catch (IllegalArgumentException e) { + LOGGER.error("Can't compute TextRange for given line {}", line, e); + return selectThisOrPreviousLine(inputFile, line - 1); + } + } else { + return selectThisOrPreviousLine(inputFile, lines); + } } - private void createExternalIssue(InputFile inputFile, Diagnostic diagnostic) { - NewExternalIssue issue = context.newExternalIssue(); - - issue.engineId("bsl-language-server"); - issue.ruleId(diagnostic.getCode()); - issue.type(ruleTypeMap.get(diagnostic.getSeverity())); - issue.severity(severityMap.get(diagnostic.getSeverity())); + private static Map createDiagnosticSeverityMap() { + Map map = new EnumMap<>(DiagnosticSeverity.class); + map.put(DiagnosticSeverity.Warning, Severity.MAJOR); + map.put(DiagnosticSeverity.Information, Severity.MINOR); + map.put(DiagnosticSeverity.Hint, Severity.INFO); + map.put(DiagnosticSeverity.Error, Severity.CRITICAL); - NewIssueLocation location = IssuesLoader.getNewIssueLocation( - issue, - inputFile, - diagnostic.getRange(), - diagnostic.getMessage() - ); - issue.at(location); + return map; + } - List relatedInformation = diagnostic.getRelatedInformation(); - if (relatedInformation != null) { - relatedInformation.forEach( - (DiagnosticRelatedInformation relatedInformationEntry) -> { - Path path = Paths.get(URI.create(relatedInformationEntry.getLocation().getUri())).toAbsolutePath(); - InputFile relatedInputFile = getInputFile(path); - if (relatedInputFile == null) { - LOGGER.warn("Can't find inputFile for absolute path {}", path); - return; - } - NewIssueLocation newIssueLocation = IssuesLoader.getNewIssueLocation( - issue, - relatedInputFile, - relatedInformationEntry.getLocation().getRange(), - relatedInformationEntry.getMessage() - ); - if (newIssueLocation != null) { - issue.addLocation(newIssueLocation); - } - } - ); - } + private static Map createRuleTypeMap() { + Map map = new EnumMap<>(DiagnosticSeverity.class); + map.put(DiagnosticSeverity.Warning, RuleType.CODE_SMELL); + map.put(DiagnosticSeverity.Information, RuleType.CODE_SMELL); + map.put(DiagnosticSeverity.Hint, RuleType.CODE_SMELL); + map.put(DiagnosticSeverity.Error, RuleType.BUG); - issue.save(); + return map; } - @CheckForNull - private InputFile getInputFile(Path path) { - return fileSystem.inputFile( - predicates.and( - predicates.hasLanguage(BSLLanguage.KEY), - predicates.hasAbsolutePath(path.toAbsolutePath().toString()) - ) - ); + @NotNull + private Map computeLoaderSettings(SensorContext context) { + var settings = ExternalReporters.REPORTERS.stream() + .map(properties -> new LoaderSettings(properties, context)) + .collect(Collectors.toMap(LoaderSettings::getRepositoryKey, Function.identity())); + settings.put(BSLLS_ENGINE_ID, new LoaderSettings(BSLLS_ENGINE_ID, + true, + BSLLanguageServerRuleDefinition.REPOSITORY_KEY)); + return settings; } - private static NewIssueLocation getNewIssueLocation( - NewExternalIssue issue, - InputFile inputFile, - Range range, - String message - ) { + public void createIssue(InputFile inputFile, Diagnostic diagnostic) { - TextRange textRange = getTextRange(inputFile, range); + var ruleId = DiagnosticCode.getStringValue(diagnostic.getCode()); - NewIssueLocation location = issue.newLocation(); + var settings = loaderSettings.get(diagnostic.getSource()); + if (settings == null) { + // считаем, что это внешняя диагностика для бсллс + settings = loaderSettings.get(BSLLS_ENGINE_ID); + } - location.on(inputFile); - location.at(textRange); - location.message(message); - return location; + var ruleKey = RuleKey.of(settings.repositoryKey, ruleId); + var activeRule = context.activeRules().find(ruleKey); + + if (settings.needCreateExternalIssues && activeRule == null) { + createExternalIssue(settings, inputFile, diagnostic); + return; + } + + var issue = context.newIssue(); + issue.forRule(ruleKey); + + Supplier newIssueLocationSupplier = issue::newLocation; + Consumer newIssueAddLocationConsumer = issue::addLocation; + Consumer newIssueAtConsumer = issue::at; + + processDiagnostic(inputFile, diagnostic, ruleId, newIssueLocationSupplier, newIssueAddLocationConsumer, newIssueAtConsumer); + + issue.save(); } - private static NewIssueLocation getNewIssueLocation( - NewIssue issue, - InputFile inputFile, - Range range, - String message - ) { - NewIssueLocation location = issue.newLocation(); + private void processDiagnostic(InputFile inputFile, Diagnostic diagnostic, String ruleId, Supplier newIssueLocationSupplier, Consumer newIssueAddLocationConsumer, Consumer newIssueAtConsumer) { - TextRange textRange = getTextRange(inputFile, range); + var textRange = getTextRange(inputFile, diagnostic.getRange(), ruleId); + var location = newIssueLocationSupplier.get(); location.on(inputFile); location.at(textRange); - location.message(message); - return location; - } + location.message(diagnostic.getMessage()); - private static TextRange getTextRange(InputFile inputFile, Range range) { - Position start = range.getStart(); - Position end = range.getEnd(); - return inputFile.newRange( - start.getLine() + 1, - start.getCharacter(), - end.getLine() + 1, - end.getCharacter() - ); + newIssueAtConsumer.accept(location); + + List relatedInformation = diagnostic.getRelatedInformation(); + if (relatedInformation != null) { + relatedInformation.forEach((DiagnosticRelatedInformation relatedInformationEntry) -> { + var path = Paths.get(URI.create(relatedInformationEntry.getLocation().getUri())).toAbsolutePath(); + var relatedInputFile = getInputFile(path); + if (relatedInputFile == null) { + LOGGER.warn("Can't find inputFile for absolute path {}", path); + return; + } + var relatedIssueLocation = newIssueLocationSupplier.get(); + + var relatedTextRange = getTextRange(relatedInputFile, relatedInformationEntry.getLocation().getRange(), ruleId); + relatedIssueLocation.on(relatedInputFile); + relatedIssueLocation.at(relatedTextRange); + relatedIssueLocation.message(relatedInformationEntry.getMessage()); + + newIssueAddLocationConsumer.accept(relatedIssueLocation); + }); + } } + private void createExternalIssue(LoaderSettings settings, InputFile inputFile, Diagnostic diagnostic) { + var issue = context.newExternalIssue(); - private static Map createDiagnosticSeverityMap() { - Map map = new EnumMap<>(DiagnosticSeverity.class); - map.put(DiagnosticSeverity.Warning, Severity.MAJOR); - map.put(DiagnosticSeverity.Information, Severity.MINOR); - map.put(DiagnosticSeverity.Hint, Severity.INFO); - map.put(DiagnosticSeverity.Error, Severity.CRITICAL); + issue.engineId(settings.engineId); - return map; + var ruleId = DiagnosticCode.getStringValue(diagnostic.getCode()); + issue.ruleId(ruleId); + + issue.type(ruleTypeMap.get(diagnostic.getSeverity())); + issue.severity(severityMap.get(diagnostic.getSeverity())); + + Supplier newIssueLocationSupplier = issue::newLocation; + Consumer newIssueAddLocationConsumer = issue::addLocation; + Consumer newIssueAtConsumer = issue::at; + + processDiagnostic(inputFile, diagnostic, ruleId, newIssueLocationSupplier, newIssueAddLocationConsumer, newIssueAtConsumer); + + issue.save(); } - private static Map createRuleTypeMap() { - Map map = new EnumMap<>(DiagnosticSeverity.class); - map.put(DiagnosticSeverity.Warning, RuleType.CODE_SMELL); - map.put(DiagnosticSeverity.Information, RuleType.CODE_SMELL); - map.put(DiagnosticSeverity.Hint, RuleType.CODE_SMELL); - map.put(DiagnosticSeverity.Error, RuleType.BUG); + @CheckForNull + private InputFile getInputFile(Path path) { + return fileSystem.inputFile(predicates.and(predicates.hasLanguage(BSLLanguage.KEY), predicates.hasAbsolutePath(path.toAbsolutePath().toString()))); + } - return map; + @Value + @AllArgsConstructor + private static class LoaderSettings { + String engineId; + boolean needCreateExternalIssues; + String repositoryKey; + + public LoaderSettings(Reporter properties, SensorContext context) { + engineId = properties.getSource(); + needCreateExternalIssues = context.config() + .getBoolean(properties.getCreateExternalIssuesKey()) + .orElse(properties.isCreateExternalIssuesDefaultValue()); + repositoryKey = properties.getRepositoryKey(); + } } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensor.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensor.java index fe61c6f5..f88960ec 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensor.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensor.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -22,8 +22,9 @@ package com.github._1c_syntax.bsl.sonar; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github._1c_syntax.bsl.languageserver.diagnostics.FileInfo; -import com.github._1c_syntax.bsl.languageserver.diagnostics.reporter.AnalysisInfo; +import com.github._1c_syntax.bsl.languageserver.reporters.data.AnalysisInfo; +import com.github._1c_syntax.bsl.languageserver.reporters.data.FileInfo; +import com.github._1c_syntax.bsl.languageserver.reporters.databind.AnalysisInfoObjectMapper; import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import org.apache.commons.io.FileUtils; import org.eclipse.lsp4j.Diagnostic; @@ -101,7 +102,7 @@ private void processFileInfo(FileInfo fileInfo) { } List diagnostics = fileInfo.getDiagnostics(); - diagnostics.forEach(diagnostic -> processDiagnostic(inputFile, diagnostic)); + diagnostics.forEach((Diagnostic diagnostic) -> processDiagnostic(inputFile, diagnostic)); } private void processDiagnostic(InputFile inputFile, Diagnostic diagnostic) { @@ -129,7 +130,7 @@ private static AnalysisInfo getAnalysisInfo(File analysisResultsFile) { return null; } - ObjectMapper objectMapper = new ObjectMapper(); + ObjectMapper objectMapper = new AnalysisInfoObjectMapper(); try { return objectMapper.readValue(json, AnalysisInfo.class); diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/AccReporter.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/AccReporter.java new file mode 100644 index 00000000..b7efa231 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/AccReporter.java @@ -0,0 +1,45 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import lombok.Value; + +/** + * Настройки внешнего анализатора 1С:АПК + */ +@Value(staticConstructor = "create") +public class AccReporter implements Reporter { + String name = "1C:ACC (1С:АПК)"; + String subcategory = "ACC"; + String enabledKey = "sonar.bsl.acc.enabled"; + boolean enableDefaultValue = false; + String createExternalIssuesKey = "sonar.bsl.acc.createExternalIssues"; + boolean createExternalIssuesDefaultValue = true; + String rulesPathsKey = "sonar.bsl.acc.accRulesPaths"; + String rulesDefaultPath = "acc.json"; + String repositoryKey = "acc-rules"; + String source = "acc"; + String repositoryName = "ACC rules"; + String ruleTag = "acc"; + int startIndex = 30; + boolean include1CCertifiedProfile = true; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/EdtReporter.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/EdtReporter.java new file mode 100644 index 00000000..8d8a6913 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/EdtReporter.java @@ -0,0 +1,45 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import lombok.Value; + +/** + * Настройки внешнего анализатора 1С:EDT + */ +@Value(staticConstructor = "create") +public class EdtReporter implements Reporter { + String name = "1C:EDT"; + String subcategory = "EDT"; + String enabledKey = "sonar.bsl.edt.enabled"; + boolean enableDefaultValue = false; + String createExternalIssuesKey = "sonar.bsl.edt.createExternalIssues"; + boolean createExternalIssuesDefaultValue = true; + String rulesPathsKey = "sonar.bsl.edt.rulesPaths"; + String rulesDefaultPath = "edt.json"; + String repositoryKey = "edt-rules"; + String source = "edt"; + String repositoryName = "EDT rules"; + String ruleTag = "edt"; + int startIndex = 35; + boolean include1CCertifiedProfile = true; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReporters.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReporters.java new file mode 100644 index 00000000..7649bba4 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReporters.java @@ -0,0 +1,38 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import lombok.experimental.UtilityClass; + +import java.util.List; + +/** + * Все зарегистрированные репортеры + */ +@UtilityClass +public class ExternalReporters { + public final List REPORTERS = List.of( + AccReporter.create(), + EdtReporter.create(), + UniversalReporter.create() + ); +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfilesContainer.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfilesContainer.java new file mode 100644 index 00000000..362d11c9 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfilesContainer.java @@ -0,0 +1,143 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; +import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; +import lombok.Getter; +import org.sonar.api.config.Configuration; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * Контейнер профилей качества внешних репортеров + */ +public class QualityProfilesContainer implements BuiltInQualityProfilesDefinition { + + private static final String PROFILE_ALL_RULES = "BSL - all rules"; + private final List qualityProfiles; + + public QualityProfilesContainer(Configuration config) { + qualityProfiles = ExternalReporters.REPORTERS.stream() + .map(reporter -> new QualityProfile(config, reporter)) + .collect(Collectors.toList()); + } + + @Override + public void define(Context context) { + var enabledQualityProfiles = qualityProfiles.stream() + .filter(QualityProfile::isEnabled).collect(Collectors.toList()); + + if (enabledQualityProfiles.isEmpty()) { + return; + } + + // добавление общего профиля для все диагностик + var rulesBSL = BSLLanguageServerRuleDefinition.getActivatedRuleKeys(); + var fullBSLProfile = context.createBuiltInQualityProfile( + PROFILE_ALL_RULES, + BSLLanguage.KEY + ); + + enabledQualityProfiles.forEach((QualityProfile qualityProfile) -> { + qualityProfile.define(context); + qualityProfile.activateDefaultRules(fullBSLProfile); + }); + + rulesBSL + .forEach(key -> fullBSLProfile.activateRule(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, key)); + fullBSLProfile.done(); + } + + /** + * Создает профили качества для внешнего репортера + */ + private static class QualityProfile { + + @Getter + private final boolean isEnabled; + private final Reporter reporter; + private final List rulesFiles = new ArrayList<>(); + + protected QualityProfile(Configuration config, Reporter reporter) { + this.reporter = reporter; + isEnabled = config.getBoolean(reporter.getEnabledKey()).orElse(reporter.isEnableDefaultValue()); + + if (isEnabled) { + rulesFiles.addAll(RulesFileReader.getRulesFiles( + reporter.getRulesDefaultPath(), + config.getStringArray(reporter.getRulesPathsKey()) + ) + ); + } + } + + protected void define(Context context) { + if (!isEnabled) { + return; + } + + addFullCheckProfile(context); + if (reporter.isInclude1CCertifiedProfile()) { + add1CCertifiedProfile(context); + } + } + + protected void activateDefaultRules(NewBuiltInQualityProfile profile) { + activateRules(profile, RulesFile.Rule::isActive); + } + + private void addFullCheckProfile(Context context) { + var profile = createQualityProfile(context, "%s - full check"); + activateDefaultRules(profile); + profile.done(); + } + + private void add1CCertifiedProfile(Context context) { + var profile = createQualityProfile(context, "%s - 1C:Compatible"); + activateRules(profile, RulesFile.Rule::isNeedForCertificate); + profile.done(); + } + + private NewBuiltInQualityProfile createQualityProfile(Context context, String nameTemplate) { + return context.createBuiltInQualityProfile( + String.format(nameTemplate, reporter.getSubcategory()), + BSLLanguage.KEY + ); + } + + private void activateRules(NewBuiltInQualityProfile profile, Predicate filter) { + rulesFiles.stream() + .map(RulesFile::getRules) + .flatMap(Collection::stream) + .filter(filter) + .map(RulesFile.Rule::getCode) + .distinct() + .forEach(key -> profile.activateRule(reporter.getRepositoryKey(), key)); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/Reporter.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/Reporter.java new file mode 100644 index 00000000..9576cd0e --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/Reporter.java @@ -0,0 +1,156 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import com.github._1c_syntax.bsl.languageserver.configuration.Language; +import org.sonar.api.Plugin; +import org.sonar.api.PropertyType; +import org.sonar.api.config.PropertyDefinition; +import org.sonar.api.resources.Qualifiers; + +import java.util.Arrays; + +import static com.github._1c_syntax.bsl.sonar.BSLCommunityProperties.BSL_CATEGORY; + +/** + * Общий интерфейс для настроек импортеров + */ +public interface Reporter { + + /** + * Пользовательское имя + */ + String getName(); + + /** + * Подкатегория настроек + */ + String getSubcategory(); + + /** + * Ключ настроек для активизации импортера + */ + String getEnabledKey(); + + /** + * Значение ключа для активизации импортера по умолчанию + */ + boolean isEnableDefaultValue(); + + /** + * Ключ настроек для создания "внешние замечаний" + */ + String getCreateExternalIssuesKey(); + + /** + * Значение по умолчанию для создания "внешние замечаний" + */ + boolean isCreateExternalIssuesDefaultValue(); + + /** + * Ключ настройки путей файлов с описанием диагностик + */ + String getRulesPathsKey(); + + /** + * Путь к поставляемому файлу описания диагностик + */ + String getRulesDefaultPath(); + + /** + * Ключ репозитория диагностик + */ + String getRepositoryKey(); + + /** + * Ключ-идентификатор репортера + */ + String getSource(); + + /** + * Пользовательское представление репозитория диагностик + */ + String getRepositoryName(); + + /** + * Имя тега, указываемого диагностикам при загрузке + */ + String getRuleTag(); + + /** + * Стартовый индекс расположения настроек в UI SQ + */ + int getStartIndex(); + + /** + * Признак необходимости создания профиля с диагностиками для 1С:Совместимо + */ + boolean isInclude1CCertifiedProfile(); + + /** + * Добавляет в контекст плагина параметры репортера для отображения в UI SQ + */ + default void addExtension(Plugin.Context context) { + var index = getStartIndex(); + Arrays.asList( + PropertyDefinition.builder(getEnabledKey()) + .name(String.format("Enable %s rules", getName())) + .description( + String.format("Enable %s rules. Need restart server", getName()) + ) + .defaultValue(Boolean.toString(isEnableDefaultValue())) + .type(PropertyType.BOOLEAN) + .options(Language.RU.getLanguageCode(), Language.EN.getLanguageCode()) + .category(BSL_CATEGORY) + .subCategory(getSubcategory()) + .onQualifiers(Qualifiers.APP) + .index(++index) + .build(), + PropertyDefinition.builder(getCreateExternalIssuesKey()) + .name("Create external issues") + .description( + String.format("Create external issue if no active %s rule was found", getSource()) + ) + .defaultValue(Boolean.toString(isCreateExternalIssuesDefaultValue())) + .type(PropertyType.BOOLEAN) + .options(Language.RU.getLanguageCode(), Language.EN.getLanguageCode()) + .category(BSL_CATEGORY) + .subCategory(getSubcategory()) + .onQualifiers(Qualifiers.APP, Qualifiers.PROJECT) + .index(++index) + .build(), + PropertyDefinition.builder(getRulesPathsKey()) + .name(String.format("%s rules path", getName())) + .description( + String.format("Path (absolute or relative) to json file with %s rules", getName()) + ) + .defaultValue("") + .type(PropertyType.STRING) + .category(BSL_CATEGORY) + .subCategory(getSubcategory()) + .onQualifiers(Qualifiers.APP) + .multiValues(true) + .index(++index) + .build() + ).forEach(context::addExtension); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionsContainer.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionsContainer.java new file mode 100644 index 00000000..704378ea --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionsContainer.java @@ -0,0 +1,102 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; +import org.sonar.api.config.Configuration; +import org.sonar.api.rules.RuleType; +import org.sonar.api.server.rule.RulesDefinition; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Контейнер диагностик внешних репортеров + */ +public class RuleDefinitionsContainer implements RulesDefinition { + + private final List ruleDefinitions; + + public RuleDefinitionsContainer(Configuration config) { + ruleDefinitions = ExternalReporters.REPORTERS.stream() + .map(reporter -> new RuleDefinition(config, reporter)) + .collect(Collectors.toList()); + } + + @Override + public void define(Context context) { + ruleDefinitions.forEach(ruleDefinition -> ruleDefinition.define(context)); + } + + private static class RuleDefinition { + + private final String[] rulesFilePaths; + private final boolean enabled; + private final String repositoryKey; + private final String repositoryName; + private final String rulesDefaultPath; + private final String ruleTag; + private NewRepository repository; + + protected RuleDefinition(Configuration config, Reporter properties) { + rulesFilePaths = config.getStringArray(properties.getRulesPathsKey()); + enabled = config.getBoolean(properties.getEnabledKey()) + .orElse(properties.isEnableDefaultValue()); + repositoryKey = properties.getRepositoryKey(); + repositoryName = properties.getRepositoryName(); + rulesDefaultPath = properties.getRulesDefaultPath(); + ruleTag = properties.getRuleTag(); + } + + protected void define(Context context) { + if (!enabled) { + return; + } + + repository = context.createRepository(repositoryKey, BSLLanguage.KEY).setName(repositoryName); + loadRules(); + repository.done(); + } + + private void loadRules() { + RulesFileReader.getRulesFiles(rulesDefaultPath, rulesFilePaths) + .forEach(file -> file.getRules().forEach(this::createRule)); + } + + private void createRule(RulesFile.Rule rule) { + var foundRule = repository.rule(rule.getCode()); + + if (foundRule == null) { + foundRule = repository.createRule(rule.getCode()).addTags(ruleTag); + } + + foundRule.setName(rule.getName()) + .setHtmlDescription(rule.getDescription()) + .setType(RuleType.valueOf(rule.getType())) + .setSeverity(rule.getSeverity()); + foundRule.setDebtRemediationFunction( + foundRule.debtRemediationFunctions().linear(rule.getEffortMinutes() + "min") + ); + } + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFile.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFile.java new file mode 100644 index 00000000..51fcfd06 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFile.java @@ -0,0 +1,83 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import lombok.AllArgsConstructor; +import lombok.Value; + +import java.util.List; + +/** + * DTO для чтения списка описаний диагностик из файла json + */ +@Value +@AllArgsConstructor +public class RulesFile { + + List rules; + + /** + * DTO для описания самих описаний диагностик в файле + */ + @Value + public static class Rule { + /** + * Код диагностики (обязательный) + */ + String code; + + /** + * Имя диагностики (обязательный) + */ + String name; + + /** + * Описание диагностики + */ + String description; + + /** + * Тип диагностики + */ + String type; + + /** + * Важность диагностики + */ + String severity; + + /** + * Признак активизации по умолчанию + */ + boolean active; + + /** + * Признак вхождения диагностики в профиль обязательных для сертификации + */ + boolean needForCertificate; + + /** + * Время на исправление (в минутах) + */ + int effortMinutes; + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFileReader.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFileReader.java new file mode 100644 index 00000000..20045608 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RulesFileReader.java @@ -0,0 +1,127 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.json.JsonMapper; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Читатель файлов с описаниями диагностик + */ +public class RulesFileReader { + + private static final Logger LOGGER = Loggers.get(RulesFileReader.class); + + private final String[] filePaths; + private int current; + + public RulesFileReader(String[] filePaths) { + this.filePaths = filePaths.clone(); + } + + /** + * Выполняет чтение описаний диагностик, включая встроенные и подгружаемые из файлов + * + * @param resourceName Имя ресурса-файла + * @param filePaths Массив путей к загружаемым файлам + * @return Список прочитанных файлов-описаний + */ + public static List getRulesFiles(String resourceName, String[] filePaths) { + List rulesFile = new ArrayList<>(); + getRulesFromResource(resourceName).ifPresent(rulesFile::add); + var loader = new RulesFileReader(filePaths); + while (loader.hasMore()) { + loader.getNext().ifPresent(rulesFile::add); + } + + return rulesFile; + } + + private static Optional getRulesFromResource(String resourceName) { + String json; + + try { + json = IOUtils.toString( + Objects.requireNonNull(RulesFileReader.class.getClassLoader().getResourceAsStream(resourceName)), + StandardCharsets.UTF_8.name() + ); + } catch (IOException e) { + LOGGER.error("Can't read json file rules", e); + return Optional.empty(); + } + + return getRulesFile(json); + } + + private static Optional getRulesFile(String json) { + var objectMapper = JsonMapper.builder() + .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) + .build(); + try { + return Optional.of(objectMapper.readValue(json, RulesFile.class)); + } catch (IOException e) { + LOGGER.error("Can't serialize json rules to object", e); + return Optional.empty(); + } + } + + private Optional getNext() { + if (hasMore()) { + Optional rules = getRulesFromFile(); + current++; + return rules; + } + + return Optional.empty(); + } + + private boolean hasMore() { + return current < filePaths.length; + } + + private Optional getRulesFromFile() { + var file = new File(filePaths[current]); + String json; + + try { + json = FileUtils.readFileToString(file, StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error("Can't read json file rules", file.toURI().toString(), e); + return Optional.empty(); + } + + return getRulesFile(json); + } + +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/UniversalReporter.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/UniversalReporter.java new file mode 100644 index 00000000..01c18edb --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/UniversalReporter.java @@ -0,0 +1,45 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import lombok.Value; + +/** + * Настройки внешнего анализатора 1С:EDT + */ +@Value(staticConstructor = "create") +public class UniversalReporter implements Reporter { + String name = "BSLLS Universal"; + String subcategory = "Universal"; + String enabledKey = "sonar.bsl.universal.enabled"; + boolean enableDefaultValue = false; + String createExternalIssuesKey = "sonar.bsl.universal.createExternalIssues"; + boolean createExternalIssuesDefaultValue = false; + String rulesPathsKey = "sonar.bsl.universal.rulesPaths"; + String rulesDefaultPath = "universal.json"; + String repositoryKey = "universal-rules"; + String source = "universal"; + String repositoryName = "Universal rules"; + String ruleTag = "bslls-universal"; + int startIndex = 45; + boolean include1CCertifiedProfile = false; +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/package-info.java new file mode 100644 index 00000000..316ca4dc --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/ext_issues/package-info.java @@ -0,0 +1,26 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +/** + * Реализация импортеров замечаний от внешних анализаторов + */ +@javax.annotation.ParametersAreNonnullByDefault +package com.github._1c_syntax.bsl.sonar.ext_issues; diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguage.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguage.java index 5647c03b..b31c1ba3 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguage.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguage.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -22,14 +22,17 @@ package com.github._1c_syntax.bsl.sonar.language; import com.github._1c_syntax.bsl.sonar.BSLCommunityProperties; +import lombok.EqualsAndHashCode; import org.sonar.api.config.Configuration; import org.sonar.api.resources.AbstractLanguage; +@EqualsAndHashCode(callSuper = false, exclude = "configuration") public class BSLLanguage extends AbstractLanguage { public static final String KEY = "bsl"; public static final String NAME = "1C (BSL)"; - private Configuration configuration; + + private final Configuration configuration; public BSLLanguage(Configuration configuration) { super(KEY, NAME); diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinition.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinition.java index f3377bfa..9699403e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinition.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinition.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,10 +21,11 @@ */ package com.github._1c_syntax.bsl.sonar.language; -import com.github._1c_syntax.bsl.languageserver.configuration.DiagnosticLanguage; -import com.github._1c_syntax.bsl.languageserver.diagnostics.BSLDiagnostic; -import com.github._1c_syntax.bsl.languageserver.diagnostics.DiagnosticSupplier; +import com.github._1c_syntax.bsl.languageserver.BSLLSBinding; +import com.github._1c_syntax.bsl.languageserver.configuration.Language; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCode; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticInfo; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameterInfo; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity; import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType; import com.github._1c_syntax.bsl.sonar.BSLCommunityProperties; @@ -52,6 +53,7 @@ public class BSLLanguageServerRuleDefinition implements RulesDefinition { public static final String REPOSITORY_KEY = "bsl-language-server"; + public static final String PARAMETERS_TAG_NAME = "parameters"; private static final String REPOSITORY_NAME = "BSL Language Server"; private static final Logger LOGGER = Loggers.get(BSLLanguageServerRuleDefinition.class); @@ -59,14 +61,15 @@ public class BSLLanguageServerRuleDefinition implements RulesDefinition { private static final Map RULE_TYPE_MAP = createRuleTypeMap(); private final Configuration config; - private final DiagnosticLanguage language; private final Parser markdownParser; private final HtmlRenderer htmlRenderer; private DiagnosticInfo diagnosticInfo; public BSLLanguageServerRuleDefinition(Configuration config) { this.config = config; - this.language = createDiagnosticLanguage(); + + var configuration = BSLLSBinding.getLanguageServerConfiguration(); + configuration.setLanguage(createDiagnosticLanguage()); List extensions = Arrays.asList( TablesExtension.create(), @@ -85,29 +88,31 @@ public BSLLanguageServerRuleDefinition(Configuration config) { @Override public void define(Context context) { - NewRepository repository = context .createRepository(REPOSITORY_KEY, BSLLanguage.KEY) .setName(REPOSITORY_NAME); - DiagnosticSupplier.getDiagnosticClasses() - .forEach((Class diagnostic) -> { - diagnosticInfo = new DiagnosticInfo(diagnostic, language); - NewRule newRule = repository.createRule(diagnosticInfo.getCode()); + var diagnosticInfos = BSLLSBinding.getDiagnosticInfos(); + + diagnosticInfos.forEach((DiagnosticInfo currentDiagnosticInfo) -> { + diagnosticInfo = currentDiagnosticInfo; + NewRule newRule = repository.createRule(diagnosticInfo.getCode().getStringValue()); setUpNewRule(newRule); setUpRuleParams(newRule); }); repository.done(); - } - protected static List getActivatedRuleKeys() { + BSLLSBinding.getApplicationContext().close(); + } - return DiagnosticSupplier.getDiagnosticClasses() + public static List getActivatedRuleKeys() { + return BSLLSBinding.getDiagnosticInfos() .stream() - .map(DiagnosticInfo::new) .filter(DiagnosticInfo::isActivatedByDefault) - .map(DiagnosticInfo::getCode).collect(Collectors.toList()); + .map(DiagnosticInfo::getCode) + .map((DiagnosticCode diagnosticCode) -> diagnosticCode.getStringValue()) + .collect(Collectors.toList()); } private void setUpNewRule(NewRule newRule) { @@ -126,6 +131,10 @@ private void setUpNewRule(NewRule newRule) { .map(String::toLowerCase) .toArray(String[]::new); + if (!diagnosticInfo.getParameters().isEmpty()) { + newRule.addTags(PARAMETERS_TAG_NAME); + } + if (tagsName.length > 0) { newRule.addTags(tagsName); } @@ -143,7 +152,7 @@ private String getHtmlDescription(String markdownDescription) { private void setUpRuleParams(NewRule newRule) { diagnosticInfo.getParameters() - .forEach(diagnosticParameter -> { + .forEach((DiagnosticParameterInfo diagnosticParameter) -> { RuleParamType ruleParamType = getRuleParamType(diagnosticParameter.getType()); if (ruleParamType == null) { LOGGER.error( @@ -163,16 +172,15 @@ private void setUpRuleParams(NewRule newRule) { }); } - private DiagnosticLanguage createDiagnosticLanguage() { + private Language createDiagnosticLanguage() { String diagnosticLanguageCode = config .get(BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_KEY) .orElse(BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_DEFAULT_VALUE); - return DiagnosticLanguage.valueOf(diagnosticLanguageCode.toUpperCase(Locale.ENGLISH)); + return Language.valueOf(diagnosticLanguageCode.toUpperCase(Locale.ENGLISH)); } - @CheckForNull private static RuleParamType getRuleParamType(Class type) { diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLQualityProfile.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLQualityProfile.java index b4bb765c..586cb81a 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLQualityProfile.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/BSLQualityProfile.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/package-info.java index a9b874c3..bb01b4c3 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/language/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/language/package-info.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * diff --git a/src/main/java/com/github/_1c_syntax/bsl/sonar/package-info.java b/src/main/java/com/github/_1c_syntax/bsl/sonar/package-info.java index fd929f40..c8fc5847 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/sonar/package-info.java +++ b/src/main/java/com/github/_1c_syntax/bsl/sonar/package-info.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * diff --git a/src/main/resources/acc.json b/src/main/resources/acc.json new file mode 100644 index 00000000..cad7bb7d --- /dev/null +++ b/src/main/resources/acc.json @@ -0,0 +1,4674 @@ +{ +"Rules": [ +{ +"Code": "100", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использован обработчик событий, подключаемый из кода и не содержащий префикса \"Подключаемый_\".", +"Description": "

Обработчики событий модуля формы, подключаемые из кода

#std492

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

Обработчикам событий модуля формы, которые устанавливаются из кода с помощью метода УстановитьДействие, рекомендуется задавать префикс Подключаемый_ (англ. Attachable_). Например:

\n

Процедура Подключаемый_РазрешитьРедактированиеРеквизитовОбъекта()

Процедура Подключаемый_КонтактнаяИнформацияНачалоВыбора()

\n

В случае когда подключение обработчика выполняется не в тексте модуля формы (а например, в общем модуле), то в результатах проверки конфигурации с включенным флажком \"Поиск неиспользуемых процедур и функций\" окажутся ошибки вида:

\n

Справочник._ДемоПартнеры.Форма.ФормаЭлемента.Форма Не обнаружено ссылок на процедуру: \" Подключаемый_КонтактнаяИнформацияНачалоВыбора\"

\n

Использование префикса позволяет легко идентифицировать такие обработчики в результатах проверки и отсеивать как исключения.

\n

Если же подключение обработчика выполняется в тексте модуля формы, то проверка конфигурации с включенным флажком \"Поиск неиспользуемых процедур и функций\" ошибку не регистрирует.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "101", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Длина выражения превышает 120 символов.", +"Description": "

Перенос выражений

#std444

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен.

\n

2. Длинные арифметические выражения переносятся следующим образом: 

\n
    \n
  • в одной строке может находиться более одного операнда;  \n
  • при переносе знаки операции пишутся в начале строки (а не в конце предыдущей строки);  \n
  • операнды на новой строке предваряются стандартным отступом, либо выравниваются по началу первого операнда без учета знаков операций.
\n

Пример:

\n

СуммаДокумента = СуммаБезСкидки
                 + СуммаРучнойСкидки
                 + СуммаАвтоматическойСкидки;

\n

или

\n

СуммаДокумента = СуммаБезСкидки
    + СуммаРучнойСкидки
    + СуммаАвтоматическойСкидки;

\n

3.1 Длинные строковые константы рекомендуется переносить с помощью специального символа перевода на новую строку, например:

\n

  ТекстЗапроса =
  \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
  | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
  |ИЗ
  | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
  |ГДЕ
  | ЗаметкиПоПредмету.Предмет = &Предмет\";

\n

или

\n

ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
  НСтр(\"ru = 'Обновление адресного классификатора не требуется.
             |В программе уже загружены актуальные адресные сведения от %1.'\"),
  Формат(ДатаПоследнегоОбновленияКЛАДР, \"ДЛФ=D\"));
ПоказатьПредупреждение(,ТекстПредупреждения);

\n

При этом не следует переносить строки, содержащие текст сообщения пользователю (объект СообщениеПользователю).

\n

3.2. В общем случае при конкатенации строк знак \"+\" рекомендуется писать в начале строки, так же как и при переносе арифметических выражений (см. п.2), например:

\n

ПоляОтбора = \"Номенклатура,Характеристика,Склад\"
   + ДополнительныеПоляОтбора;

\n

3.3. При конкатенации длинных строк знак \"+\" можно писать в конце строки, чтобы не ломать общее форматирование текста. Например,

\n

ТекстЗапроса = ТекстЗапроса +
\"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник. Номенклатура КАК Номенклатура\";

\n

4. При необходимости параметры процедур, функций и методов следует переносить следующим образом: 

\n
    \n
  • параметры выравниваются по началу первого параметра, либо предваряются стандартным отступом;  \n
  • закрывающая скобка и разделитель операторов \";\" пишутся в той же строке, что и последний параметр; \n
  • также допустим и способ форматирования, который предлагает функция автоформатирования в конфигураторе (см. п. 5).
\n

Пример:

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
                         Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
                         Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

или

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
    Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
    Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

5. Сложные логические условия в Если…ИначеЕсли…КонецЕсли следует переносить следующим образом: 

\n
    \n
  • каждое элементарное условие нужно начинать с новой строки, если длина строки превышает ограничение в 120 символов;  \n
  • логические операторы И, ИЛИ ставятся в начале строки, а не в конце предыдущей строки;  \n
  • все условия предваряются стандартным отступом, либо выравниваются по началу первого условия, без учета логического оператора (для выравнивания выражений относительно первой строки рекомендуется использовать пробелы).
\n

Примеры:

\n

Если (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозница)
  ИЛИ (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозницаКомиссия) Тогда
  Возврат Истина;
КонецЕсли;

\n

Если ((СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокПроцедуры)
  ИЛИ(СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокФункции))
  И(Найти(ВРЕГ(СтруктураМодуля[Индекс].Текст), КлючБлока)> 0) Тогда

\n

6. Для выполнения перечисленных выше рекомендаций, кроме автоматического форматирования текста программного модуля, в процессе ввода можно также отформатировать уже введенный текст. Для этого необходимо выделить блок текста, который требуется отформатировать, и выбрать пункт меню Текст — Блок — Форматировать. При этом текстовый редактор проанализирует текст модуля и выполнит его форматирование, при котором содержимое каждой синтаксической конструкции будет сдвинуто вправо на величину табуляции независимо от первоначального расположения строк (лидирующих пробелов). В пустые строки устанавливаются знаки табуляции в соответствии с синтаксической конструкцией.

\n

Для автоматической расстановки переносов строк можно воспользоваться приложенной обработкой.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "102", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Неправильный перенос текста в выражении.", +"Description": "

Перенос выражений

#std444

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен.

\n

2. Длинные арифметические выражения переносятся следующим образом: 

\n
    \n
  • в одной строке может находиться более одного операнда;  \n
  • при переносе знаки операции пишутся в начале строки (а не в конце предыдущей строки);  \n
  • операнды на новой строке предваряются стандартным отступом, либо выравниваются по началу первого операнда без учета знаков операций.
\n

Пример:

\n

СуммаДокумента = СуммаБезСкидки
                 + СуммаРучнойСкидки
                 + СуммаАвтоматическойСкидки;

\n

или

\n

СуммаДокумента = СуммаБезСкидки
    + СуммаРучнойСкидки
    + СуммаАвтоматическойСкидки;

\n

3.1 Длинные строковые константы рекомендуется переносить с помощью специального символа перевода на новую строку, например:

\n

  ТекстЗапроса =
  \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
  | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
  |ИЗ
  | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
  |ГДЕ
  | ЗаметкиПоПредмету.Предмет = &Предмет\";

\n

или

\n

ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
  НСтр(\"ru = 'Обновление адресного классификатора не требуется.
             |В программе уже загружены актуальные адресные сведения от %1.'\"),
  Формат(ДатаПоследнегоОбновленияКЛАДР, \"ДЛФ=D\"));
ПоказатьПредупреждение(,ТекстПредупреждения);

\n

При этом не следует переносить строки, содержащие текст сообщения пользователю (объект СообщениеПользователю).

\n

3.2. В общем случае при конкатенации строк знак \"+\" рекомендуется писать в начале строки, так же как и при переносе арифметических выражений (см. п.2), например:

\n

ПоляОтбора = \"Номенклатура,Характеристика,Склад\"
   + ДополнительныеПоляОтбора;

\n

3.3. При конкатенации длинных строк знак \"+\" можно писать в конце строки, чтобы не ломать общее форматирование текста. Например,

\n

ТекстЗапроса = ТекстЗапроса +
\"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник. Номенклатура КАК Номенклатура\";

\n

4. При необходимости параметры процедур, функций и методов следует переносить следующим образом: 

\n
    \n
  • параметры выравниваются по началу первого параметра, либо предваряются стандартным отступом;  \n
  • закрывающая скобка и разделитель операторов \";\" пишутся в той же строке, что и последний параметр; \n
  • также допустим и способ форматирования, который предлагает функция автоформатирования в конфигураторе (см. п. 5).
\n

Пример:

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
                         Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
                         Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

или

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
    Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
    Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

5. Сложные логические условия в Если…ИначеЕсли…КонецЕсли следует переносить следующим образом: 

\n
    \n
  • каждое элементарное условие нужно начинать с новой строки, если длина строки превышает ограничение в 120 символов;  \n
  • логические операторы И, ИЛИ ставятся в начале строки, а не в конце предыдущей строки;  \n
  • все условия предваряются стандартным отступом, либо выравниваются по началу первого условия, без учета логического оператора (для выравнивания выражений относительно первой строки рекомендуется использовать пробелы).
\n

Примеры:

\n

Если (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозница)
  ИЛИ (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозницаКомиссия) Тогда
  Возврат Истина;
КонецЕсли;

\n

Если ((СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокПроцедуры)
  ИЛИ(СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокФункции))
  И(Найти(ВРЕГ(СтруктураМодуля[Индекс].Текст), КлючБлока)> 0) Тогда

\n

6. Для выполнения перечисленных выше рекомендаций, кроме автоматического форматирования текста программного модуля, в процессе ввода можно также отформатировать уже введенный текст. Для этого необходимо выделить блок текста, который требуется отформатировать, и выбрать пункт меню Текст — Блок — Форматировать. При этом текстовый редактор проанализирует текст модуля и выполнит его форматирование, при котором содержимое каждой синтаксической конструкции будет сдвинуто вправо на величину табуляции независимо от первоначального расположения строк (лидирующих пробелов). В пустые строки устанавливаются знаки табуляции в соответствии с синтаксической конструкцией.

\n

Для автоматической расстановки переносов строк можно воспользоваться приложенной обработкой.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1026", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в заголовке формы.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1027", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в заголовке элемента формы.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1028", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в колонке табличного поля.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "103", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Строка должна находиться в конце предыдущей.", +"Description": "

Перенос выражений

#std444

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен.

\n

2. Длинные арифметические выражения переносятся следующим образом: 

\n
    \n
  • в одной строке может находиться более одного операнда;  \n
  • при переносе знаки операции пишутся в начале строки (а не в конце предыдущей строки);  \n
  • операнды на новой строке предваряются стандартным отступом, либо выравниваются по началу первого операнда без учета знаков операций.
\n

Пример:

\n

СуммаДокумента = СуммаБезСкидки
                 + СуммаРучнойСкидки
                 + СуммаАвтоматическойСкидки;

\n

или

\n

СуммаДокумента = СуммаБезСкидки
    + СуммаРучнойСкидки
    + СуммаАвтоматическойСкидки;

\n

3.1 Длинные строковые константы рекомендуется переносить с помощью специального символа перевода на новую строку, например:

\n

  ТекстЗапроса =
  \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
  | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
  |ИЗ
  | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
  |ГДЕ
  | ЗаметкиПоПредмету.Предмет = &Предмет\";

\n

или

\n

ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
  НСтр(\"ru = 'Обновление адресного классификатора не требуется.
             |В программе уже загружены актуальные адресные сведения от %1.'\"),
  Формат(ДатаПоследнегоОбновленияКЛАДР, \"ДЛФ=D\"));
ПоказатьПредупреждение(,ТекстПредупреждения);

\n

При этом не следует переносить строки, содержащие текст сообщения пользователю (объект СообщениеПользователю).

\n

3.2. В общем случае при конкатенации строк знак \"+\" рекомендуется писать в начале строки, так же как и при переносе арифметических выражений (см. п.2), например:

\n

ПоляОтбора = \"Номенклатура,Характеристика,Склад\"
   + ДополнительныеПоляОтбора;

\n

3.3. При конкатенации длинных строк знак \"+\" можно писать в конце строки, чтобы не ломать общее форматирование текста. Например,

\n

ТекстЗапроса = ТекстЗапроса +
\"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник. Номенклатура КАК Номенклатура\";

\n

4. При необходимости параметры процедур, функций и методов следует переносить следующим образом: 

\n
    \n
  • параметры выравниваются по началу первого параметра, либо предваряются стандартным отступом;  \n
  • закрывающая скобка и разделитель операторов \";\" пишутся в той же строке, что и последний параметр; \n
  • также допустим и способ форматирования, который предлагает функция автоформатирования в конфигураторе (см. п. 5).
\n

Пример:

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
                         Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
                         Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

или

\n

ИменаДокументов = Новый СписокЗначений;
ИменаДокументов.Добавить(Метаданные.Документы.СтрокаВыпискиРасход.Имя, 
    Метаданные.Документы.СтрокаВыпискиРасход.Синоним);
ИменаДокументов.Добавить(Метаданные.Документы.РасходныйКассовыйОрдер.Имя, 
    Метаданные.Документы.РасходныйКассовыйОрдер.Синоним);

\n

5. Сложные логические условия в Если…ИначеЕсли…КонецЕсли следует переносить следующим образом: 

\n
    \n
  • каждое элементарное условие нужно начинать с новой строки, если длина строки превышает ограничение в 120 символов;  \n
  • логические операторы И, ИЛИ ставятся в начале строки, а не в конце предыдущей строки;  \n
  • все условия предваряются стандартным отступом, либо выравниваются по началу первого условия, без учета логического оператора (для выравнивания выражений относительно первой строки рекомендуется использовать пробелы).
\n

Примеры:

\n

Если (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозница)
  ИЛИ (ВидОперации = Перечисления.ВидыОперацийПоступлениеМПЗ.ПоступлениеРозницаКомиссия) Тогда
  Возврат Истина;
КонецЕсли;

\n

Если ((СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокПроцедуры)
  ИЛИ(СтруктураМодуля[Индекс].Блок = Перечисления.ТипыБлоковМодулей.ЗаголовокФункции))
  И(Найти(ВРЕГ(СтруктураМодуля[Индекс].Текст), КлючБлока)> 0) Тогда

\n

6. Для выполнения перечисленных выше рекомендаций, кроме автоматического форматирования текста программного модуля, в процессе ввода можно также отформатировать уже введенный текст. Для этого необходимо выделить блок текста, который требуется отформатировать, и выбрать пункт меню Текст — Блок — Форматировать. При этом текстовый редактор проанализирует текст модуля и выполнит его форматирование, при котором содержимое каждой синтаксической конструкции будет сдвинуто вправо на величину табуляции независимо от первоначального расположения строк (лидирующих пробелов). В пустые строки устанавливаются знаки табуляции в соответствии с синтаксической конструкцией.

\n

Для автоматической расстановки переносов строк можно воспользоваться приложенной обработкой.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1030", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в подсказке элемента управления.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1032", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в синониме объекта метаданных.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1033", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в комментарии объекта метаданных.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1034", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в тексте встроенной справки.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1035", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в тексте макета.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1036", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в тексте модуля.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1037", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в видимой колонке табличного поля.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1038", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в тексте видимого элемента формы.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "104", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована директива компиляции.", +"Description": "

Использование директив компиляции и инструкций препроцессора

#std439

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Директивы компиляции:

\n

&НаКлиенте (&AtClient)
&НаСервере (&AtServer)
&НаСервереБезКонтекста (&AtServerNoContext)

\n

следует применять только в коде модулей управляемых форм и в коде модулей команд. В остальных модулях рекомендуется применять инструкции препроцессору.

\n

В серверных или клиентских общих модулях контекст исполнения очевиден, поэтому смысла в директивах компиляции нет. В общих модулях с признаками клиент и сервер применение директив компиляции затрудняет понимание, какие же процедуры (функции) доступны в конечном итоге.

\n

2. Не следует использовать инструкции препроцессора в клиент-серверных общих модулях для проверки клиентского и серверного контекстов (#Если Сервер, #Если Клиент) ввиду невозможности надежного определения контекста исполнения. Процедуры и функции, которые работают по-разному при вызове с клиента и с сервера, следует размещать в общих модулях с постфиксами Клиент и Сервер, а не КлиентСервер.

\n

В противном случае невозможно гарантировать корректную работу клиент-серверных процедур и функций в различных режимах работы платформы 1С:Предприятие.

\n

Например, неправильно:

\n

Функция КодОсновногоЯзыка() Экспорт
#Если НЕ ТонкийКлиент И НЕ ВебКлиент Тогда
 Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
#Иначе
 Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(\"КодОсновногоЯзыка\");
#КонецЕсли
КонецФункции

\n

также неправильно:

\n

Функция КодОсновногоЯзыка() Экспорт
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
 Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
#Иначе
 Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(\"КодОсновногоЯзыка\");
#КонецЕсли
КонецФункции

\n

Правильно: разделить на две одноименные функции в серверном и клиентском модуле с различной реализацией. В общем случае, когда у них имеется определенная общая часть, одинаковая для клиента и сервера, то для того чтобы избежать дублирования кода, этот общий код (и только его) следует оставить в клиент-серверном общем модуле и вызывать его из клиентской и серверной функций, соответственно. Тем самым надежно достигается различное поведение в клиентском и серверном контекстах без использования инструкций препроцессора.

\n

В то же время, как и в обычных клиентских модулях, допустимо ветвление кода для учета специфики различных режимов работы клиентского приложения: веб-клиент, тонкий или толстый клиент (например, #Если ВебКлиент).

\n

3. Не следует разрывать инструкциями препроцессора и областями отдельные грамматические конструкции, выражения, а также объявления и места вызова процедур и функций.

\n

Например, неправильно:

\n

Процедура Пример1()
  а = 1
#Область ИмяОбласти
    + 2;
#КонецОбласти // разрыв выражения
КонецПроцедуры

\n

#Область ИмяОбласти
Процедура Пример2()
    // ...
#КонецОбласти // разрыв процедуры
КонецПроцедуры

\n

Если <...> Тогда
    // ...
#Если ВебКлиент Тогда // разрыв блока Если
Иначе
    // ...
#КонецЕсли
КонецЕсли;

\n

Результат = Пример4(Параметр1,
#Если Клиент Тогда
  Параметр2, // некорректный вызов функции
#КонецЕсли
  Параметр3);

\n

Данные ошибки диагностируются автоматически с помощью среды разработки 1C:Enterprise Development Tools (EDT).

\n

Правильно использовать инструкции препроцессора без разрыва конструкций.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "1046", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует обязательная роль.", +"Description": "

Стандартные роли

#std488

Область применения: управляемое приложение, обычное приложение.

\n

1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

\n

1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

\n

Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

\n

2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

\n

2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • позволять самостоятельное использование (может быть назначена пользователям); \n
  • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
  • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
  • включать в себя перечисленные права: \n
      \n
    • Администрирование данных \n
    • Активные пользователи \n
    • Журнал регистрации \n
    • Монопольный режим \n
    • Тонкий клиент \n
    • Веб-клиент \n
    • Сохранение данных пользователя \n
    • Вывод
\n

В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

\n

При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

\n

2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • \n
    \n
    назначаться пользователям только совместно с ролью ПолныеПрава;
    \n
  • \n
    \n
    предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
    \n
  • \n
    содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
    \n
  • \n
    включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
Эта роль должна:

\n
    \n
  • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

\n

При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

\n

2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

\n

\n\n\n\n
\n

Методическая рекомендация (полезный совет)

\n

2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

\n

3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

\n

Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

\n

3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

\n

3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

\n

3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

\n

3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

\n

3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

\n

3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

\n

3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

\n

3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

\n

3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

\n

3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

\n

3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

\n

3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

\n

Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

\n
    \n
  • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
  • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
  • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
\n

то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

\n

При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

\n
\n

См. также: Работа с пользовательскими настройками

\n

4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

\n

4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

\n

4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

\n

При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

\n

5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

\n
    \n
  • Право интерактивного удаления \n
  • Интерактивное удаление предопределенных данных \n
  • Интерактивная пометка удаления предопределенных данных \n
  • Интерактивное снятие пометки удаления предопределенных данных \n
  • Интерактивное удаление помеченных предопределенных данных
\n

Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

\n

См. также

\n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "105", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована явная запись наборов записей регистров (с помощью метода Записать) в процедуре обработки проведения.", +"Description": "

Порядок записи движений документов

#std450

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Не рекомендуется использовать явную запись наборов записей регистров (с помощью метода Записать) в процедурах обработки проведения документов. Запись должна производится неявно системой, при завершении процедуры проведения.

В случае же нарушения этого правила, при параллельной работе нескольких пользователей, возможна ситуация возникновения взаимных блокировок при проведении документов.

2. Исключением является ситуация, когда данные, сохраняемые в регистрах, необходимы в последующих алгоритмах, выполняемых до момента выхода из процедуры проведения.

\n

См. также

\n\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "108", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Документ не имеет реквизита \"Комментарий\".", +"Description": "

Реквизит «Комментарий» у документов

#std531

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

Методическая рекомендация (полезный совет)

\n

1. Для всех документов рекомендуется создавать реквизит Комментарий (строка неограниченной длины). В этом реквизите пользователи могут записывать по документу различные заметки служебного характера, которые не относятся к прикладной специфике документа (например, причина пометки на удаления и т.п.). Доступ к реквизиту для пользователей должен быть настроен также как и к самому документу (если документ доступен только для чтения, то и комментарий – только для чтения; если же есть право записи документа, то и значение реквизита также можно изменять).

\n

2. Если же штатный сценарий работы пользователя предусматривает внесение произвольной текстовой информации в документ, то для этого необходимо предусмотреть отдельные реквизиты «прикладного» характера. Например, в документе Заказ клиента для описания дополнительных договоренностей с клиентом следует предусмотреть реквизит Дополнительная информация, а не пользоваться служебным реквизитом Комментарий.

\n

3. В простейшем случае, в качестве внешнего редактора текста комментария рекомендуется использовать функцию ВвестиСтроку. При использовании в конфигурации Библиотеки стандартных подсистем можно воспользоваться специализированной процедурой ПоказатьФормуРедактированияКомментария общего модуля ОбщегоНазначенияКлиент.

\n

См. также

\n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "109", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Реквизит \"Комментарий\" имеет недопустимый тип.", +"Description": "

Реквизит «Комментарий» у документов

#std531

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

Методическая рекомендация (полезный совет)

\n

1. Для всех документов рекомендуется создавать реквизит Комментарий (строка неограниченной длины). В этом реквизите пользователи могут записывать по документу различные заметки служебного характера, которые не относятся к прикладной специфике документа (например, причина пометки на удаления и т.п.). Доступ к реквизиту для пользователей должен быть настроен также как и к самому документу (если документ доступен только для чтения, то и комментарий – только для чтения; если же есть право записи документа, то и значение реквизита также можно изменять).

\n

2. Если же штатный сценарий работы пользователя предусматривает внесение произвольной текстовой информации в документ, то для этого необходимо предусмотреть отдельные реквизиты «прикладного» характера. Например, в документе Заказ клиента для описания дополнительных договоренностей с клиентом следует предусмотреть реквизит Дополнительная информация, а не пользоваться служебным реквизитом Комментарий.

\n

3. В простейшем случае, в качестве внешнего редактора текста комментария рекомендуется использовать функцию ВвестиСтроку. При использовании в конфигурации Библиотеки стандартных подсистем можно воспользоваться специализированной процедурой ПоказатьФормуРедактированияКомментария общего модуля ОбщегоНазначенияКлиент.

\n

См. также

\n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "110", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Форма документа имеет элементы управления, расположенные ниже комментария.", +"Description": "

Поля \"Ответственный\" и \"Комментарий\"

#std587

Область применения: управляемое приложение.

\n

См. также: Поля \"Ответственный\" и \"Комментарий\" (8.3)

\n


Поля \"Ответственный\" и \"Комментарий\", используемые в формах документов, необходимо располагать и оформлять в соответствии со следующими рекомендациями.

\n

 

\n

1. Расположение группы полей \"Ответственный\" и \"Комментарий\"

\n
\n

Группу полей \"Ответственный\" и \"Комментарий\" следует располагать в самом низу формы, друг за другом:

\n

\n

2. Оформление поля «Ответственный»

\n
\n

• Поле не растягивается на всю ширину формы

\n


• Для поля подбирается такая ширина,  чтобы в него полностью помещались типичные выбираемые значения. На максимально возможные значения ориентироваться не следует.

\n

\n

 

\n

3. Оформление поля «Комментарий»

\n
\n

• Заголовок располагается слева от поля

\n


• Поле растягивается по горизонтали на всю ширину формы

\n


• Поле не растягивается по вертикали

\n

 

\n

Как правило, поле \"Комментарий\" является многострочным (свойство \"МногострочныйРежим\" = Да). В случае, если в поле \"Комментарий\" всегда будет вводиться небольшое количество информации, его рекомендуется делать однострочным (свойство \"МногострочныйРежим\" = Авто).
Решение о том, каким должно быть поле – однострочным или многострочным –
 принимается разработчиком исходя из прикладных требований.

\n

3.1. Оформление многострочного поля \"Комментарий\":

\n
\n

\n

• Высота поля – две строки
• Используется кнопка выбора, по которой открывается окно редактора многострочного текста (блокирующее):

\n

\n

 

\n

 3.2. Оформление однострочного поля \"Комментарий\":

\n

\n

·         Высота поля – одна строка

\n

·         Кнопка выбора не используется

\n

\n

Если поле «Комментарий» в типовых случаях будет большим, то допускается вынести его на отдельную вкладку

\n

 

\n

4. Оформление вкладки «Комментарий»

\n
\n

• Заголовок вкладки – «Комментарий»

\n


• На вкладке размещается поле с текстом комментария, которое растягивается по вертикали и по горизонтали. Заголовок поля не отражается

\n


• Если поле с комментарием заполнено, то в заголовке вкладки отражается картинка «Комментарий»

\n

 

\n

См. также: Реквизит \"Комментарий\" у документов

\n


 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1108", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Нарушена сортировка объектов метаданных верхнего уровня по имени по возрастанию в дереве метаданных.", +"Description": "

Общие требования к конфигурации

#std467

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
Дополнительные материалы:

\n\n

1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

\n\n

1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

\n
    \n
  • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
  • придерживаться общей схемы установки признаков общих модулей, \n
  • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
\n

Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

\n

1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

\n

2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

\n

2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

\n

2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

\n

Исключение составляют:

\n
    \n
  • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
  • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "111", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Поле комментарий должно быть многострочным.", +"Description": "

Поля \"Ответственный\" и \"Комментарий\"

#std587

Область применения: управляемое приложение.

\n

См. также: Поля \"Ответственный\" и \"Комментарий\" (8.3)

\n


Поля \"Ответственный\" и \"Комментарий\", используемые в формах документов, необходимо располагать и оформлять в соответствии со следующими рекомендациями.

\n

 

\n

1. Расположение группы полей \"Ответственный\" и \"Комментарий\"

\n
\n

Группу полей \"Ответственный\" и \"Комментарий\" следует располагать в самом низу формы, друг за другом:

\n

\n

2. Оформление поля «Ответственный»

\n
\n

• Поле не растягивается на всю ширину формы

\n


• Для поля подбирается такая ширина,  чтобы в него полностью помещались типичные выбираемые значения. На максимально возможные значения ориентироваться не следует.

\n

\n

 

\n

3. Оформление поля «Комментарий»

\n
\n

• Заголовок располагается слева от поля

\n


• Поле растягивается по горизонтали на всю ширину формы

\n


• Поле не растягивается по вертикали

\n

 

\n

Как правило, поле \"Комментарий\" является многострочным (свойство \"МногострочныйРежим\" = Да). В случае, если в поле \"Комментарий\" всегда будет вводиться небольшое количество информации, его рекомендуется делать однострочным (свойство \"МногострочныйРежим\" = Авто).
Решение о том, каким должно быть поле – однострочным или многострочным –
 принимается разработчиком исходя из прикладных требований.

\n

3.1. Оформление многострочного поля \"Комментарий\":

\n
\n

\n

• Высота поля – две строки
• Используется кнопка выбора, по которой открывается окно редактора многострочного текста (блокирующее):

\n

\n

 

\n

 3.2. Оформление однострочного поля \"Комментарий\":

\n

\n

·         Высота поля – одна строка

\n

·         Кнопка выбора не используется

\n

\n

Если поле «Комментарий» в типовых случаях будет большим, то допускается вынести его на отдельную вкладку

\n

 

\n

4. Оформление вкладки «Комментарий»

\n
\n

• Заголовок вкладки – «Комментарий»

\n


• На вкладке размещается поле с текстом комментария, которое растягивается по вертикали и по горизонтали. Заголовок поля не отражается

\n


• Если поле с комментарием заполнено, то в заголовке вкладки отражается картинка «Комментарий»

\n

 

\n

См. также: Реквизит \"Комментарий\" у документов

\n


 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1125", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В форме неверно установлен стиль.", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1126", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ТекстПредупреждающейНадписи\".", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1127", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Шрифт: ШрифтВажнойНадписи\".", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1128", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ФонГруппировкиВерхнегоУровня\".", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1129", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ФонГруппировкиПромежуточногоУровня\".", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "113", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Размер элемента управления типа \"Кнопка\" меньше 60х19.", +"Description": "

Кнопки

#std516

Область применения: обычное приложение.

\n

Обычное приложение

\n

Кнопки размещаются вне командных панелей. Минимальный размер кнопок: 60х19. Шарина кнопки может увеличиваться в зависимости от длины строки заголовка кнопки. Надпись на кнопке должна занимать одну строку.

\n

Оформление кнопок с часто употребимыми действиями (частотных кнопок)

\n

Для оформления кнопок с часто употребимыми действиями (частотных кнопок) рекомендуется использовать текст совместно с картинкой.

\n

Иконка, размещенная на кнопке, также может использоваться в строке табличной части для дополнительной идентификации типа данных, к которому применима данная команда.

\n

Пример: Форма реализации товаров и услуг, кнопка Состав набора (\"Редактировать состава набора комплекта\").

\n

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1130", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ТекстИнформационнойНадписи\".", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1131", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно определен основной стиль для конфигурации.", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1132", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не установлен основной стиль для конфигурации.", +"Description": "

Стили

#std524

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

\n

2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

\n
    \n
  • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
  • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
  • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
  • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
  • Цвет ЦветГиперссылки - цвет текста гиперссылки.
\n

 

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1133", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлен признак переключения для интерфейса \"Общий\".", +"Description": "

Общие интерфейсы

#std501

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для отображения общих для всех переключаемых прикладных интерфейсов пунктов меню и панелей инструментов в конфигурации создается интерфейс Общий. У него снимается признак Переключаемый, а в качестве подсистемы указывается вся конфигурация.

\n

2. На верхнем уровне главного меню должны обязательно располагаться в крайней левой позиции подменю Файл и в крайней правой позиции набор подменю Сервис, Окна, Справка.

\n

3. В меню Сервис может присутствовать подменю Переключить интерфейс для переключения текущего интерфейса на другой. Подменю должно содержать список всех переключаемых интерфейсов конфигурации.

\n

4. В интерфейсе Общий рекомендуется отключать подменю Операции, кроме случаев, когда это подменю используется во всех переключаемых интерфейсах конфигурации.

\n

5. В конфигурации может быть создано несколько непереключаемых интерфейсов для того, чтобы реализовать зависимость состава главного меню и панелей инструментов от роли пользователя. Для этого состав интерфейсов конфигурации дополняется интерфейсами, названия которых начинаются со слова Общий…. Для таких интерфейсов снимается признак Переключаемый и право на их использование дается тем или иным ролям.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1134", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В конфигурации отсутствует обязательный интерфейс \"Общий\".", +"Description": "

Общие правила построения интерфейсов

#std500

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для каждой укрупненной группы пользователей (рабочего места) в конфигурации рекомендуется определять отдельный интерфейс: главное меню, набор и состав панелей инструментов.

\n

2.1. Главное меню обеспечивает доступ ко всем формам, которые требуются пользователю для работы или сервисных функций. В подменю с большим числом элементов, группы элементов должны быть ограничены разделителями. Максимальное число элементов в одной группе не более 7.

\n

2.2. При любом положении выбора действия из главного меню, его размер должен быть таким, чтобы полностью умещаться на экране при минимальном разрешении, из расчета на которое разработана конфигурация.

\n

2.3. По умолчанию пункты меню для доступа к справочникам, документам, планам видов характеристик, планам счетов, планам видов расчетов и регистрам вызывают формы списков этих объектов.

\n

3.1. Интерфейс следует проектировать таким образом, чтобы группе пользователей, с одной стороны, был доступен необходимый набор действий, а с другой, не предоставлялся доступ к действиям на которые нет прав. Вызовы наиболее часто выполняемых пользователем действий в интерфейсе лучше располагать так, чтобы они были наиболее доступны, и наоборот.

\n

3.2. Желательно однотипные блоки меню и панелей инструментов в разных интерфейсах делать похожим образом.

\n

4. В каждой конфигурации обязательно должны быть интерфейсы Общий и Полный.

\n

См. также

\n\n

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1135", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В конфигурации отсутствует обязательный интерфейс \"Полный\".", +"Description": "

Общие правила построения интерфейсов

#std500

Область применения: обычное приложение.

\n

Обычное приложение

\n

1. Для каждой укрупненной группы пользователей (рабочего места) в конфигурации рекомендуется определять отдельный интерфейс: главное меню, набор и состав панелей инструментов.

\n

2.1. Главное меню обеспечивает доступ ко всем формам, которые требуются пользователю для работы или сервисных функций. В подменю с большим числом элементов, группы элементов должны быть ограничены разделителями. Максимальное число элементов в одной группе не более 7.

\n

2.2. При любом положении выбора действия из главного меню, его размер должен быть таким, чтобы полностью умещаться на экране при минимальном разрешении, из расчета на которое разработана конфигурация.

\n

2.3. По умолчанию пункты меню для доступа к справочникам, документам, планам видов характеристик, планам счетов, планам видов расчетов и регистрам вызывают формы списков этих объектов.

\n

3.1. Интерфейс следует проектировать таким образом, чтобы группе пользователей, с одной стороны, был доступен необходимый набор действий, а с другой, не предоставлялся доступ к действиям на которые нет прав. Вызовы наиболее часто выполняемых пользователем действий в интерфейсе лучше располагать так, чтобы они были наиболее доступны, и наоборот.

\n

3.2. Желательно однотипные блоки меню и панелей инструментов в разных интерфейсах делать похожим образом.

\n

4. В каждой конфигурации обязательно должны быть интерфейсы Общий и Полный.

\n

См. также

\n\n

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1136", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не заполнена всплывающая подсказка.", +"Description": "

Подсказки

#std506

Область применения: обычное приложение.

\n

Обычное приложение

\n

С целью пояснить назначение элемента управления ему назначается подсказка. Подсказка должна быть лаконичной, длина текста подсказки не должна превышать 8 слов. Заполнение подсказки обязательно.

", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "114", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Элемент управления типа \"Кнопка\" содержит многострочный заголовок.", +"Description": "

Кнопки

#std516

Область применения: обычное приложение.

\n

Обычное приложение

\n

Кнопки размещаются вне командных панелей. Минимальный размер кнопок: 60х19. Шарина кнопки может увеличиваться в зависимости от длины строки заголовка кнопки. Надпись на кнопке должна занимать одну строку.

\n

Оформление кнопок с часто употребимыми действиями (частотных кнопок)

\n

Для оформления кнопок с часто употребимыми действиями (частотных кнопок) рекомендуется использовать текст совместно с картинкой.

\n

Иконка, размещенная на кнопке, также может использоваться в строке табличной части для дополнительной идентификации типа данных, к которому применима данная команда.

\n

Пример: Форма реализации товаров и услуг, кнопка Состав набора (\"Редактировать состава набора комплекта\").

\n

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1147", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не задана принадлежность объекта к подсистемам.", +"Description": "

Отнесение объектов библиотек к подсистемам

#std705

Область применения: управляемое приложение, обычное приложение.

\n

1. Все объекты библиотеки должны быть отнесены к одной корневой подсистеме (например, для объектов БСП – это подсистема СтандартныеПодсистемы), которая не содержит командного интерфейса.

\n

2. Допустимо наличие нескольких корневых подсистем (помимо упомянутой в п.1), содержащих командный интерфейс.

\n

См. также

\n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1149", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлено право \"Интерактивное удаление\".", +"Description": "

Стандартные роли

#std488

Область применения: управляемое приложение, обычное приложение.

\n

1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

\n

1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

\n

Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

\n

2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

\n

2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • позволять самостоятельное использование (может быть назначена пользователям); \n
  • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
  • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
  • включать в себя перечисленные права: \n
      \n
    • Администрирование данных \n
    • Активные пользователи \n
    • Журнал регистрации \n
    • Монопольный режим \n
    • Тонкий клиент \n
    • Веб-клиент \n
    • Сохранение данных пользователя \n
    • Вывод
\n

В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

\n

При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

\n

2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • \n
    \n
    назначаться пользователям только совместно с ролью ПолныеПрава;
    \n
  • \n
    \n
    предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
    \n
  • \n
    содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
    \n
  • \n
    включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
Эта роль должна:

\n
    \n
  • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

\n

При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

\n

2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

\n

\n\n\n\n
\n

Методическая рекомендация (полезный совет)

\n

2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

\n

3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

\n

Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

\n

3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

\n

3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

\n

3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

\n

3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

\n

3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

\n

3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

\n

3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

\n

3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

\n

3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

\n

3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

\n

3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

\n

3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

\n

Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

\n
    \n
  • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
  • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
  • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
\n

то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

\n

При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

\n
\n

См. также: Работа с пользовательскими настройками

\n

4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

\n

4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

\n

4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

\n

При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

\n

5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

\n
    \n
  • Право интерактивного удаления \n
  • Интерактивное удаление предопределенных данных \n
  • Интерактивная пометка удаления предопределенных данных \n
  • Интерактивное снятие пометки удаления предопределенных данных \n
  • Интерактивное удаление помеченных предопределенных данных
\n

Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

\n

См. также

\n\n\n\n

Использование предопределенных элементов

#std697

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

\n

1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

\n

1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

\n

Для этого

\n
    \n
  • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
  • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
      \n
    • ИнтерактивноеУдалениеПредопределенныхДанных \n
    • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
    • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
    • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
\n\n\n\n
\n
\n

Область применения (уточнение): управляемое приложение, обычное приложение.

\n

1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

\n

При этом:

\n

а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

\n

б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

\n

в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

\n

Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
 // заполняем предопределенные элементы
 // ...
КонецЕсли;

\n

При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

\n

1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

\n

Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

\n

При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

\n

Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

\n

2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

\n

Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

\n

Для этого

\n
    \n
  • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
  • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
\n

Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
 НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
 НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
 // ...
 НачислениеОбъект.Записать();
КонецЕсли;  

\n
    \n
  • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
\n

  ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
  ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

\n

При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

\n

  ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

\n

См. также

\n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "115", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Элемент управления типа \"Кнопка\" находится на командной панели.", +"Description": "

Кнопки

#std516

Область применения: обычное приложение.

\n

Обычное приложение

\n

Кнопки размещаются вне командных панелей. Минимальный размер кнопок: 60х19. Шарина кнопки может увеличиваться в зависимости от длины строки заголовка кнопки. Надпись на кнопке должна занимать одну строку.

\n

Оформление кнопок с часто употребимыми действиями (частотных кнопок)

\n

Для оформления кнопок с часто употребимыми действиями (частотных кнопок) рекомендуется использовать текст совместно с картинкой.

\n

Иконка, размещенная на кнопке, также может использоваться в строке табличной части для дополнительной идентификации типа данных, к которому применима данная команда.

\n

Пример: Форма реализации товаров и услуг, кнопка Состав набора (\"Редактировать состава набора комплекта\").

\n

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1150", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не установлено право в роли \"ПолныеПрава\".", +"Description": "

Стандартные роли

#std488

Область применения: управляемое приложение, обычное приложение.

\n

1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

\n

1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

\n

Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

\n

2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

\n

2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • позволять самостоятельное использование (может быть назначена пользователям); \n
  • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
  • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
  • включать в себя перечисленные права: \n
      \n
    • Администрирование данных \n
    • Активные пользователи \n
    • Журнал регистрации \n
    • Монопольный режим \n
    • Тонкий клиент \n
    • Веб-клиент \n
    • Сохранение данных пользователя \n
    • Вывод
\n

В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

\n

При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

\n

2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
Эта роль должна:

\n
    \n
  • \n
    \n
    назначаться пользователям только совместно с ролью ПолныеПрава;
    \n
  • \n
    \n
    предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
    \n
  • \n
    содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
    \n
  • \n
    включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
Эта роль должна:

\n
    \n
  • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
\n

При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

\n

При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

\n

2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

\n

\n\n\n\n
\n

Методическая рекомендация (полезный совет)

\n

2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

\n

3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

\n

Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

\n

3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

\n

3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

\n

3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

\n

3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

\n

3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

\n

3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

\n

3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

\n

3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

\n

3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

\n

3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

\n

3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

\n

3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

\n

Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

\n
    \n
  • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
  • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
  • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
\n

то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

\n

При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

\n
\n

См. также: Работа с пользовательскими настройками

\n

4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

\n

4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

\n

4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

\n

При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

\n

5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

\n
    \n
  • Право интерактивного удаления \n
  • Интерактивное удаление предопределенных данных \n
  • Интерактивная пометка удаления предопределенных данных \n
  • Интерактивное снятие пометки удаления предопределенных данных \n
  • Интерактивное удаление помеченных предопределенных данных
\n

Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

\n

См. также

\n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "1151", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не задан синоним объекта метаданных.", +"Description": "

Имя, синоним, комментарий

#std474

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

\n

Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

\n

1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

\n

1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

\n

В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
правильно: «Загрузка данных из Microsoft Excel».

\n

1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

\n

1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
неправильно

\n
    \n
  • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
\n

правильно

\n
    \n
  • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
\n

Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

\n
\n

См. также: Пользовательские представления объектов, Тексты

\n

1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

\n

Например, неправильно давать справочникам следующие синонимы:

\n
    \n
  • Банковские счета, \n
  • Банковские счета контрагентов
\n

правильно:

\n
    \n
  • Банковские счета организаций, \n
  • и Банковские счета контрагентов
\n

Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

\n

Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
Неправильно:

\n
    \n
  • Количество \n
  • Количество (по учету)
\n

правильно:

\n
    \n
  • Количество (в наличии) \n
  • Количество (по учету)
\n

Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
Неправильно:

\n
    \n
  • Наименование \n
  • Полное наименование
\n

правильно:

\n
    \n
  • Рабочее наименование \n
  • Наименование для печати
\n

2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
Например, неправильно:

\n
    \n
  • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
  • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
\n

правильно:

\n
    \n
  • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
  • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
\n

Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

\n
    \n
  • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
  • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
  • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
\n

Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

\n

А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

\n

Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

\n
\n

См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

\n

2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

\n

Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

\n

2.3. Имена объектов метаданных не должны превышать 80 символов.

\n

2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

\n

2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

\n

ВЫБРАТЬ
Сведения.Сведения
ИЗ
РегистрСведений.Сведения КАК Сведения

\n

3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

\n

3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

\n

См. также

\n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "117", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Ширина вертикального разделителя не соответствует требованиям.", +"Description": "

Разделители

#std515

Область применения: обычное приложение.

\n

Обычное приложение

\n

\n

При построении форм используются вертикальные и горизонтальные разделители. Вертикальным разделителям устанавливается ширина 6, горизонтальную привязку рекомендуется устанавливать в НеПривязано. Горизонтальным разделителям устанавливается высота 6, вертикальную привязку рекомендуется устанавливать в НеПривязано.

\n

Рамку рекомендуется устанавливать в НетРамки. В сложных случаях, когда пользователю может быть тяжело догадаться о наличие разделителя, допускается устанавливать рамку Одинарная.

\n

Наличие разделителя должно интуитивно угадываться при работе с формой, поэтому ближайшие от разделителя по направлениям его передвижения элементы управления размещаются вплотную к нему, таким образом визуально предполагая его расположение.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "118", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Высота горизонтального разделителя не соответствует требованиям.", +"Description": "

Разделители

#std515

Область применения: обычное приложение.

\n

Обычное приложение

\n

\n

При построении форм используются вертикальные и горизонтальные разделители. Вертикальным разделителям устанавливается ширина 6, горизонтальную привязку рекомендуется устанавливать в НеПривязано. Горизонтальным разделителям устанавливается высота 6, вертикальную привязку рекомендуется устанавливать в НеПривязано.

\n

Рамку рекомендуется устанавливать в НетРамки. В сложных случаях, когда пользователю может быть тяжело догадаться о наличие разделителя, допускается устанавливать рамку Одинарная.

\n

Наличие разделителя должно интуитивно угадываться при работе с формой, поэтому ближайшие от разделителя по направлениям его передвижения элементы управления размещаются вплотную к нему, таким образом визуально предполагая его расположение.

", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "120", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Расположение закладок у панели не соответствует требованиям.", +"Description": "

Использование закладок

#std511

Область применения: обычное приложение.

\n

Обычное приложение

\n

Запрещается делать несколько страниц у самой формы.

\n

У панелей рекомендуется делать не более 5 одновременно видимых закладок. Расположение закладок – сверху.

\n

Допускается большее количество закладок многостраничной панели и/или расположение закладок слева: 

\n
    \n
  • для специализированных форм настроек параметров; \n
  • для форм, в которых страницы панели генерируются программно.
", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1200", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно установлен номер версии. Правильный формат \"РР.ПП.ЗЗ.СС\".", +"Description": "

Нумерация редакций и версий

#std483

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Номер очередной редакции конфигурации, начинается со следующего целого номера относительно предыдущей редакции. Для обозначения редакции обычно номер редакции объединяют через точку с номером подредакции, например: редакция 1.5, редакция 1.6 и т. д. Для новых конфигураций нумерация начинается с 1.0.

2. Все версии одной подредакции (включая альфа, ознакомительные, бета и финальные версии) нумеруются подряд. Нумерация версий начинается с 1.

3. Информация о номере редакции, номере подредакции и номере версии объединяются в полный номер версии конфигурации. Он указывается в свойстве Версия конфигурации и представляет собой строку символов следующего вида:

{Р|РР}.{П|ПП}.{З|ЗЗ}.{С|СС}

где:
Р - номер редакции (минимум 1 цифра, может занимать и больше разрядов);
П - номер подредакции (минимум 1 цифра, может занимать и больше разрядов);
З - номер версии (минимум 1 цифра, может занимать и больше разрядов);
С - номер сборки (минимум 1 цифра, может занимать и больше разрядов).

Пример:

\n
\n
1.6.4.7 – 7-я сборка, 4-ой версии, редакции 1.6
\n

См. также

\n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1201", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Краткая информация отличается от синонима.", +"Description": "

Заполнение свойств конфигурации информацией о выпуске

#std482

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

\n

Например: \"Бухгалтерия предприятия, редакция 1.6\"

\n

2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

\n

Например: \"БухгалтерияПредприятия\"

\n

3. Краткая информация. Краткая информация повторяет синоним.

\n

4. Подробная информация. Подробная информация повторяет синоним.

\n

5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

\n

6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

\n

7. Авторские права. Указывается строка вида:

\n

Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

\n

Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

\n

Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

\n

Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

\n

8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
http://www.1c.ru

\n

9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

/\">http://v8.1c.ru/<короткое имя>/,

\n

где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

\n

http://v8.1c.ru/trade/

\n

10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

\n

Фирма \"1С\"

\n

11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

\n

Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

\n

12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

http://downloads.v8.1c.ru/tmplts/

", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1202", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Подробная информация отличается от синонима.", +"Description": "

Заполнение свойств конфигурации информацией о выпуске

#std482

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

\n

Например: \"Бухгалтерия предприятия, редакция 1.6\"

\n

2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

\n

Например: \"БухгалтерияПредприятия\"

\n

3. Краткая информация. Краткая информация повторяет синоним.

\n

4. Подробная информация. Подробная информация повторяет синоним.

\n

5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

\n

6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

\n

7. Авторские права. Указывается строка вида:

\n

Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

\n

Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

\n

Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

\n

Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

\n

8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
http://www.1c.ru

\n

9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

/\">http://v8.1c.ru/<короткое имя>/,

\n

где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

\n

http://v8.1c.ru/trade/

\n

10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

\n

Фирма \"1С\"

\n

11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

\n

Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

\n

12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

http://downloads.v8.1c.ru/tmplts/

", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1203", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Неверно указан поставщик. Должен быть \"Фирма \"1С\"\".", +"Description": "

Заполнение свойств конфигурации информацией о выпуске

#std482

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

\n

Например: \"Бухгалтерия предприятия, редакция 1.6\"

\n

2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

\n

Например: \"БухгалтерияПредприятия\"

\n

3. Краткая информация. Краткая информация повторяет синоним.

\n

4. Подробная информация. Подробная информация повторяет синоним.

\n

5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

\n

6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

\n

7. Авторские права. Указывается строка вида:

\n

Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

\n

Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

\n

Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

\n

Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

\n

8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
http://www.1c.ru

\n

9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

/\">http://v8.1c.ru/<короткое имя>/,

\n

где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

\n

http://v8.1c.ru/trade/

\n

10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

\n

Фирма \"1С\"

\n

11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

\n

Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

\n

12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

\n

http://downloads.v8.1c.ru/tmplts/

", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1205", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Реквизит имеет тип фиксированной строки.", +"Description": "

Использование реквизитов строкового типа

#std432

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n

1.1. Для реквизитов строкового типа следует использовать переменную длину строки (свойство Допустимая длина = Переменная) и при этом указывать максимально допустимую длину строки. Свойство Допустимая длина может принимать значение Фиксированная только в тех случаях, когда при манипуляции этими данными действительно необходимо иметь гарантию, что строка имеет определенную длину (за счет автоматического дополнения концевыми пробелами).

\n

1.2. В тех случаях, когда максимальная длина строки заранее известна (например, она регламентирована), следует указывать ее в свойстве Длина (или Длина наименования для стандартного реквизита Наименование). Например, длина строкового реквизита ИНН справочника ФизическиеЛица должна составлять 12 символов.

\n

1.3. Если строка является конкатенацией других строк, то ее длина может быть определена как сумма длин исходных строк. Например, длина представления адреса должно равняться сумме длин полей, в которых хранятся части адреса.

\n

1.4 Если длина строки не регламентирована, то рекомендуется выбирать такую длину, которой достаточно для хранения данных в большинстве случаев. Например, для хранения полного наименования контрагента в подавляющем большинстве случаев достаточно 250 символов, максимальная длина имени файла в большинстве файловых систем – 260, полное имя физического лица – 100 и т.п.

\n

2. В отдельных случаях, допускается использование строк неограниченной длины:

\n

2.1. Предполагается, что в реквизит строкового типа может быть помещен пользовательский текст, объем которого может быть значительным. Как правило, это многострочные поля на форме. Например, в поле Дополнительное описание в заказе клиента менеджер может поместить всю историю переписки с клиентом, в поле Комментарий – пользователь может ввести произвольный многострочный текст и т.п.

\n

2.2. В строковом реквизите хранится различная техническая информация, которая генерируется программами и, чаще всего, не предназначена для чтения пользователем, а используется в различных алгоритмах обработки информации. Например, xml-документы, заголовки почтовых сообщений и т.п.

\n

3. В случае использования строковых реквизитов неограниченной длины следует иметь в виду возникающие при этом ограничения в языке запросов:

\n

3.1. При необходимости сравнения значений, группировки и получения различных, такие реквизиты необходимо выражать как строку определенной длины, такой, чтобы выражение было вычислено верно.

\n

Для этих целей в запросе рекомендуется использовать конструкцию

\n

ВЫРАЗИТЬ КАК СТРОКА(1000)

\n

3.2. В отчетах СКД для таких полей следует, вместо этого, задавать параметр Тип значения поля (на закладке Наборы данных).

\n

Следует иметь в виду, что частое приведение неограниченной строки к определенной длине в запросах и отчетах СКД может быть признаком неправильного проектного решения и служить сигналом для пересмотра типа строкового реквизита в пользу ограниченной длины строки. 

\n

3.3. В остальных случаях, урезать строку в запросах не требуется.

\n

4. Если в печатных формах предусмотрено отображение строкового поля, то независимо от того, какая назначена длина строки, необходимо обеспечить вывод таких строк полностью, без обрезания части строки. В противном случае, может быть утеряна значимая часть информации. Например, номер дома и квартиры в поле с адресом доставки товара в печатной форме.

\n

Для быстрого выявления в конфигурации всех строковых реквизитов неограниченной длины можно воспользоваться приложенной обработкой СтрокиНеограниченнойДлины.erf

\n

См. также

\n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1206", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Нестандартная длина кода (номера), проверьте оправданность использования такой длины.", +"Description": "

Использование кодов (номеров) объектов конфигурации

#std473

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

\n\n\n\n
\n

Методическая рекомендация (полезный совет)

\n

Длины кодов (номеров) объектов конфигурации задаются в зависимости от их прикладного смысла.

\n
    \n
  1. Необходимость применения кодов (номеров) объектов конфигурации определяется из их прикладного смысла. Основания для применения кодов (номеров):  \n

    1.1. Пользователям предстоит работать со списками, содержащими большое количество элементов.
    Пример: справочник Номенклатура.

    \n

    1.2. Искать данные по коду (номеру) удобнее, чем по другим свойствам.
    Например, справочник Статьи расходов. Пользователю проще запомнить код, чем каждый раз вчитываться в название статьи. Кроме того, названия статей могут меняться.

    \n

    1.3. Код имеет прикладной смысл, продиктованный спецификой автоматизируемой области.
    Например, код справочника Единицы измерения соответствует коду единицы измерения в ОКЕИ, код справочника Номера ГТД соответствует номеру грузовой таможенной декларации и т.д.


    \n
  2. Необходимость применения автонумерации объектов конфигурации отсутствует в следующих случаях: \n

    2.1. Код используется как краткое представление элемента данных в виде строки.
    Например, для справочника Пользователи автонумерация не применяется, т.к. в коде хранится краткое имя пользователя (логин).

    \n

    2.2. Код (номер) получается из внешних источников (т.н. входящие данные).
    Например, это все классификаторы.
    Другой пример - справочник Номера ГТД, код которого вводится исходя из данных входящих документов.


    \n
  3. Длина кода (номера) устанавливается в зависимости от его прикладного назначения и метода получения (ввода): \n

    3.1. Для объектов с автонумерацией длина кода (номера) выбирается, исходя из потенциального количества всех объектов, хранимых в базе данных;
    объектов, относящихся к определенному периоду (для документов и бизнес-процессов);
    или объектов, относящихся к определенному владельцу (иерархические и подчиненные справочники, задачи).
    При этом в длине номера необходимо учитывать длину префиксов нумерации, например, префикс информационной базы, префикс организации, если это предусмотрено конфигурацией и т.п.

    \n

    При разработке типовых конфигураций рекомендуемыми, но не обязательными к применению являются длины кодов (номеров) из следующего ряда: 3, 5, 9, 11. При этом в длине номера необходимо учитывать длину префиксов нумерации, например, префикс информационной базы, префикс организации, если это предусмотрено конфигурацией и т.п.

    \n

    Если в конфигурации используется подсистема Префиксация объектов из Библиотеки стандартных подсистем, то совокупную длину (с учетом префикса) номеров документов и кодов справочников рекомендуется устанавливать не менее 11 символов (11, 13, 15, …). Подробнее см. документацию к подсистеме \"Префиксация объектов\" на ИТС.

    \n

    3.2. Для объектов, в которых код используется как краткое представление элемента данных в виде строки (см. п. 2.1) длина кода устанавливается достаточной для хранения краткого строкового представления объектов исходя из прикладного смысла кода.

    \n

    3.3. Для объектов, в которых код (номер) получается из внешних источников (см. п. 2.2), длина кода (номера) зависит от этого источника.

    \n

    3.4. Рекомендуется устанавливать допустимую длину кода (номера) объектов переменной.


    \n
  4. \n

    В случае если прикладное решение рассчитано на работу с данными, которые могут вводиться параллельно из нескольких мест (в рамках РИБ, в других программах), в нем должна быть реализована возможность автоматической префиксации объектов конфигурации, для которых выполняются следующие условия:
    - используется строковый код (номер),
    - используется автонумерация,
    - данные, соответствующие области, в пределах которой коды (номера) должны быть уникальными, могут вводиться параллельно из нескольких мест (узлов РИБ, программ) и впоследствии консолидироваться, например, в результате выполнения синхронизации данных. Пример такой области для большинства видов документов – организация и период.
    При использовании в конфигурации Библиотеки стандартных подсистем реализовать данное требование позволяет подсистема Префиксация объектов.

    \n
    ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1207", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Совпадают имена у объекта метаданных и его составляющей.", +"Description": "

    Имя, синоним, комментарий

    #std474

    Область применения: управляемое приложение, мобильное приложение, обычное приложение.

    \n

    1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

    \n

    Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

    \n

    1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

    \n

    1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

    \n

    В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
    Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
    правильно: «Загрузка данных из Microsoft Excel».

    \n

    1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

    \n

    1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
    неправильно

    \n
      \n
    • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
    \n

    правильно

    \n
      \n
    • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
    \n

    Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

    \n
    \n

    См. также: Пользовательские представления объектов, Тексты

    \n

    1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

    \n

    Например, неправильно давать справочникам следующие синонимы:

    \n
      \n
    • Банковские счета, \n
    • Банковские счета контрагентов
    \n

    правильно:

    \n
      \n
    • Банковские счета организаций, \n
    • и Банковские счета контрагентов
    \n

    Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

    \n

    Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
    Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
    Неправильно:

    \n
      \n
    • Количество \n
    • Количество (по учету)
    \n

    правильно:

    \n
      \n
    • Количество (в наличии) \n
    • Количество (по учету)
    \n

    Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
    Неправильно:

    \n
      \n
    • Наименование \n
    • Полное наименование
    \n

    правильно:

    \n
      \n
    • Рабочее наименование \n
    • Наименование для печати
    \n

    2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
    Например, неправильно:

    \n
      \n
    • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
    • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
    \n

    правильно:

    \n
      \n
    • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
    • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
    \n

    Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

    \n
      \n
    • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
    • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
    • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
    \n

    Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

    \n

    А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

    \n

    Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

    \n
    \n

    См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

    \n

    2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

    \n

    Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

    \n

    2.3. Имена объектов метаданных не должны превышать 80 символов.

    \n

    2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

    \n

    2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

    \n

    ВЫБРАТЬ
    Сведения.Сведения
    ИЗ
    РегистрСведений.Сведения КАК Сведения

    \n

    3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

    \n

    3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

    4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

    \n

    См. также

    \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "1208", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Присвоено нерекомендуемое имя.", +"Description": "

    Имя, синоним, комментарий

    #std474

    Область применения: управляемое приложение, мобильное приложение, обычное приложение.

    \n

    1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

    \n

    Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

    \n

    1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

    \n

    1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

    \n

    В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
    Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
    правильно: «Загрузка данных из Microsoft Excel».

    \n

    1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

    \n

    1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
    неправильно

    \n
      \n
    • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
    \n

    правильно

    \n
      \n
    • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
    \n

    Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

    \n
    \n

    См. также: Пользовательские представления объектов, Тексты

    \n

    1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

    \n

    Например, неправильно давать справочникам следующие синонимы:

    \n
      \n
    • Банковские счета, \n
    • Банковские счета контрагентов
    \n

    правильно:

    \n
      \n
    • Банковские счета организаций, \n
    • и Банковские счета контрагентов
    \n

    Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

    \n

    Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
    Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
    Неправильно:

    \n
      \n
    • Количество \n
    • Количество (по учету)
    \n

    правильно:

    \n
      \n
    • Количество (в наличии) \n
    • Количество (по учету)
    \n

    Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
    Неправильно:

    \n
      \n
    • Наименование \n
    • Полное наименование
    \n

    правильно:

    \n
      \n
    • Рабочее наименование \n
    • Наименование для печати
    \n

    2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
    Например, неправильно:

    \n
      \n
    • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
    • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
    \n

    правильно:

    \n
      \n
    • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
    • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
    \n

    Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

    \n
      \n
    • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
    • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
    • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
    \n

    Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

    \n

    А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

    \n

    Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

    \n
    \n

    См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

    \n

    2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

    \n

    Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

    \n

    2.3. Имена объектов метаданных не должны превышать 80 символов.

    \n

    2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

    \n

    2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

    \n

    ВЫБРАТЬ
    Сведения.Сведения
    ИЗ
    РегистрСведений.Сведения КАК Сведения

    \n

    3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

    \n

    3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

    4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

    \n

    См. также

    \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "1209", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Нестандартная длина номера, проверьте оправданность использования такой длины.", +"Description": "

    Использование кодов (номеров) объектов конфигурации

    #std473

    Область применения: управляемое приложение, мобильное приложение, обычное приложение.

    \n\n\n\n
    \n

    Методическая рекомендация (полезный совет)

    \n

    Длины кодов (номеров) объектов конфигурации задаются в зависимости от их прикладного смысла.

    \n
      \n
    1. Необходимость применения кодов (номеров) объектов конфигурации определяется из их прикладного смысла. Основания для применения кодов (номеров):  \n

      1.1. Пользователям предстоит работать со списками, содержащими большое количество элементов.
      Пример: справочник Номенклатура.

      \n

      1.2. Искать данные по коду (номеру) удобнее, чем по другим свойствам.
      Например, справочник Статьи расходов. Пользователю проще запомнить код, чем каждый раз вчитываться в название статьи. Кроме того, названия статей могут меняться.

      \n

      1.3. Код имеет прикладной смысл, продиктованный спецификой автоматизируемой области.
      Например, код справочника Единицы измерения соответствует коду единицы измерения в ОКЕИ, код справочника Номера ГТД соответствует номеру грузовой таможенной декларации и т.д.


      \n
    2. Необходимость применения автонумерации объектов конфигурации отсутствует в следующих случаях: \n

      2.1. Код используется как краткое представление элемента данных в виде строки.
      Например, для справочника Пользователи автонумерация не применяется, т.к. в коде хранится краткое имя пользователя (логин).

      \n

      2.2. Код (номер) получается из внешних источников (т.н. входящие данные).
      Например, это все классификаторы.
      Другой пример - справочник Номера ГТД, код которого вводится исходя из данных входящих документов.


      \n
    3. Длина кода (номера) устанавливается в зависимости от его прикладного назначения и метода получения (ввода): \n

      3.1. Для объектов с автонумерацией длина кода (номера) выбирается, исходя из потенциального количества всех объектов, хранимых в базе данных;
      объектов, относящихся к определенному периоду (для документов и бизнес-процессов);
      или объектов, относящихся к определенному владельцу (иерархические и подчиненные справочники, задачи).
      При этом в длине номера необходимо учитывать длину префиксов нумерации, например, префикс информационной базы, префикс организации, если это предусмотрено конфигурацией и т.п.

      \n

      При разработке типовых конфигураций рекомендуемыми, но не обязательными к применению являются длины кодов (номеров) из следующего ряда: 3, 5, 9, 11. При этом в длине номера необходимо учитывать длину префиксов нумерации, например, префикс информационной базы, префикс организации, если это предусмотрено конфигурацией и т.п.

      \n

      Если в конфигурации используется подсистема Префиксация объектов из Библиотеки стандартных подсистем, то совокупную длину (с учетом префикса) номеров документов и кодов справочников рекомендуется устанавливать не менее 11 символов (11, 13, 15, …). Подробнее см. документацию к подсистеме \"Префиксация объектов\" на ИТС.

      \n

      3.2. Для объектов, в которых код используется как краткое представление элемента данных в виде строки (см. п. 2.1) длина кода устанавливается достаточной для хранения краткого строкового представления объектов исходя из прикладного смысла кода.

      \n

      3.3. Для объектов, в которых код (номер) получается из внешних источников (см. п. 2.2), длина кода (номера) зависит от этого источника.

      \n

      3.4. Рекомендуется устанавливать допустимую длину кода (номера) объектов переменной.


      \n
    4. \n

      В случае если прикладное решение рассчитано на работу с данными, которые могут вводиться параллельно из нескольких мест (в рамках РИБ, в других программах), в нем должна быть реализована возможность автоматической префиксации объектов конфигурации, для которых выполняются следующие условия:
      - используется строковый код (номер),
      - используется автонумерация,
      - данные, соответствующие области, в пределах которой коды (номера) должны быть уникальными, могут вводиться параллельно из нескольких мест (узлов РИБ, программ) и впоследствии консолидироваться, например, в результате выполнения синхронизации данных. Пример такой области для большинства видов документов – организация и период.
      При использовании в конфигурации Библиотеки стандартных подсистем реализовать данное требование позволяет подсистема Префиксация объектов.

      \n
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1210", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Представление объекта совпадает с синонимом. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1211", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Расширенное представление объекта совпадает с представлением объекта. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1213", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Расширенное представление объекта совпадает с синонимом при незаполненном представлении объекта. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1214", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Представление списка совпадает с синонимом. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1215", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Расширенное представление списка совпадает с представлением списка. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1216", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Расширенное представление списка совпадает с синонимом при незаполненном представлении списка. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1217", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Расширенное представление совпадает с синонимом. В этом случае оно не заполняется.", +"Description": "

      Пользовательские представления объектов

      #std468

      Область применения: управляемое приложение.

      \n

      Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

      1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n
      \n

      См. также: Имя, синоним, комментарий, Тексты

      \n

      2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

      \n

      Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

      3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

      4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

      \n

      Заполняется в случае, если синоним не может быть использован, как название списка объектов.

      5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

      \n

      Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

      6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

      \n

      Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

      7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

      \n

      Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

      8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1218", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Объект метаданных является демонстрационным.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1221", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ТекстВторостепеннойНадписи\".", +"Description": "

      Стили

      #std524

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

      \n

      2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

      \n
        \n
      • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
      • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
      • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
      • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
      • Цвет ЦветГиперссылки - цвет текста гиперссылки.
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1222", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определен обязательный элемент стиля \"Цвет: ЦветГиперссылки\".", +"Description": "

      Стили

      #std524

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      1. Для оформления конфигурации используется стиль Основной. Он устанавливается в целом для конфигурации (в свойстве Основной стиль объекта метаданных конфигурации). Для форм конфигурации устанавливается стиль Авто.

      \n

      2. Кроме элементов стиля, определенных платформой 1С:Предприятие, для оформления используются 5 элементов стиля, определенных в конфигурации:

      \n
        \n
      • Цвет ТекстИнформационнойНадписи - цвет текста информационных надписей;  \n
      • Цвет ТекстПредупреждающейНадписи - цвет текста предупреждающих надписей;  \n
      • Шрифт ШрифтВажнойНадписи - шрифт текста важной надписи;  \n
      • Цвет ТекстВторостепеннойНадписи - цвет текста второстепенных надписей;  \n
      • Цвет ЦветГиперссылки - цвет текста гиперссылки.
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1223", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Сообщение содержит нерекомендуемое местоимение (\"Вы\", \"Вас\" и пр.).", +"Description": "

      Сообщения пользователю

      #std585

      Область применения: управляемое приложение.

      \n

       

      \n

      1. Общие рекомендации

      \n

       

      \n

      1.1. Сообщения должны быть достаточно информативными и содержательными. Сообщения составляются в форме безличного предложения: не употребляются местоимения \"Вы\", \"Вас\" и пр.  

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Недостаточно прав для выполнения обработки\"

      \n

      \"У Вас недостаточно прав для выполнения обработки\"

      \n

       

      \n

      1.2. Сообщения не должны содержать восклицательных знаков и повелительных тонов, за исключением сообщений, предупреждающих об опасных или критических действиях. 

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Внимание. Загрузка базы может привести к потере всех данных\"

      \n

       

      \n

       

      \n

       

      \n

       

      \n

      \"Выберите элемент, а не группу\"

      \n

       

      \n

      \"Внимание! Загрузка базы может привести к потере всех данных\"

      \n

      Это сообщение не акцентирует внимание пользователя на том, что последствия могут критичны

      \n


      \"Выберите элемент, а не группу!\"

      \n

      Это сообщение несет негативный настрой, а также заставляет пользователя чувствовать себя глупо

      \n

       

      \n

      1.3. Сообщение должно быть написано текстом, понятным пользователю. В частности, оно не должно содержать технической терминологии (терминологии разработчика). Подобную терминологию допускается использовать только в сообщениях, предназначенных для администратора.

      \n

      Например, если пользователь указал в качестве кассы отправителя и кассы получателя одно и то же значение, то выводится  сообщение: \"Касса отправителя равна кассе получателя\".

      \n

      В реальности касса не может быть равна другой – она может быть одной и той же.

      \n


       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Касса отправителя и касса получателя должны различаться\"

      \n

      \"Касса отправителя равна кассе получателя\"

      \n

       

      \n

      1.4. Сообщения, указывающие на ошибку, должны выводиться в момент возникновения ошибки.

      \n

      Например, в отчете, сдаваемом в Пенсионный фонд, указываются  регистрационные номера сотрудников. Эти номера заполняются в карточке сотрудника.
      Проверку  правильности заполнения этого номера нужно делать в момент его  ввода в карточке, а не в момент формирования отчета.

      \n

       

      \n

      1.5. В тексте сообщений необходимо избегать двусмысленности. Категорически запрещается постановка вопроса с содержанием частиц \"не\" и \"бы\". Подобные вопросы не способны дать однозначного ответа.

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Удалить файл?\"

      \n

      \"Не хотели бы вы удалить этот файл?\" (Да / Нет)
      \"Переместить или удалить этот файл?\" (Да / Нет)

      \n

       

      \n

      1.6. В текстах сообщений не следует использовать сокращения и аббревиатуры. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения и аббревиатуры.
      Например, сокращения \"НДС\", \"МСФО\" понятны пользователям, а \"К.\" (коэффициент) – нет.

      \n

       

      \n

      1.7. Если текст сообщения занимает несколько строк, рекомендуется составлять его таким образом, чтобы строки оканчивались на логическую паузу или завершались знаком препинания.

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      Не рекомендуется изменять значение ставки налога,
      если она уже используется в справочниках или документах.

      \n

      Не рекомендуется изменять значение ставки налога, если
      она уже используется в справочниках или документах.

      \n

       

      \n

      1.8. Следует руководствоваться принципом, что в процедурах и функциях, выполняемых в транзакции, нельзя выполнять каких-либо взаимодействий с пользователем – выводить предупреждения и вопросы.

      \n

       

      \n

      1.9. Сообщения, оповещения, предупреждения или состояние не следует использовать в случае, если нужно вывести протокол, отчет или подробности о результатах выполненной операции. Для этого следует предусмотреть специальную форму.

      \n

      2. Сообщение об ошибках в форме

      \n

      \n

      Сообщения об ошибках в форме выводятся в панели сообщений об ошибках справа:

      \n

      \n

       

      \n

      2.1. В панели сообщений следует выводить только сообщения об ошибках. Сообщения об успешном завершении операции в панели выводить запрещается.

      \n


       

      \n

      2.2. Сообщение об ошибке по возможности должно быть привязано к полю, которое породило ошибку или позволяет исправить ее. Если сообщение нельзя привязать к тому или иному полю, то в тексте сообщения следует явно указать, что пользователю нужно сделать для того, чтобы устранить проблему.

      \n

       

      \n

      2.3. Сообщения об ошибках должны отвечать на 3 вопроса:

      \n
        \n
      • Что произошло? \n
      • Почему это произошло? \n
      • Что делать дальше?
      \n

      Ответов на эти вопросы должно хватить пользователю, чтобы принять решение о дальнейших действиях, а также не повторить данной ошибки в будущем.

      \n

      Например, пользователь пытается изменить статус документа, помеченного на удаление.
      Система выдает сообщение: \"Документ \"Коммерческое предложение <номер> не проведен. Статус не изменен\"

      \n

      Сообщение создает новый вопрос для пользователя: почему не изменен статус? В тексте сообщения отсутствует информация о том, что документ помечен на удаление, и что именно это является причиной возникновения ошибки.

      \n

       

      \n

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Невозможно изменить статус: документ \"Коммерческое предложение <номер> помечен на удаление\"

      \n

      \"Документ \"Коммерческое предложение <номер> не проведен. Статус не изменен\"

      \n

      2.4. Следует учитывать, что в панели сообщений текст сообщения автоматически форматируется, а строки переносятся, сохраняя при этом свои пропорции. Поэтому текст таких сообщений не нужно разбивать на строки.

      \n

      См. также: Перенос выражений

      \n

      2.5. Сообщение должно быть как можно более кратким и понятным.
      Если же поле заполнено, но неправильно, то сообщение должно быть более подробным.
      Например, \"Указанного количества товара <название товара> нет на складе. Доступно: <количество доступно> <единица измерения>\".

      \n

      2.6. Текст сообщения об ошибке должен содержать побудительную часть, призывающую пользователя совершить действия по исправлению ошибки.

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Укажите хотя бы одну систему налогообложения\"

      \n

       

      \n

      \"Необходимо указать хотя бы одну систему налогообложения\"

      \n

       

      \n

      3. Оповещение

      \n

       

      \n

      \n

      \n

      \n

      3.1. Рекомендуется использовать оповещение для информирования пользователя о произошедших событиях без прерывания основной работы. Пользователю не обязательно реагировать на оповещение, оно выдается для информации.
      Оповещение сообщает о том, что запрошенная операция (запись элемента справочника или проведение документа) выполнена.

      \n

       

      \n

      3.2. Оповещения рекомендуется делать с гиперссылками на соответствующие объекты.

      \n

       

      \n

      3.3. Текст и пояснение оповещения рекомендуется составлять так, чтобы они целиком помещались в окне оповещения с размерами \"по умолчанию\":

      \n
        \n
      • Текст – 36 знаков; \n
      • Пояснение  – около 100 знаков (с учетом переноса на три строки).
      \n

       

      \n

      4. Состояние

      \n

       

      \n

      4.1. Рекомендуется использовать состояние для информирования о выполнении длительных процессов (занимающих более 10 секунд), чтобы у пользователей не сложилось впечатление о том, что программа \"зависла\". Выводите состояние:

      \n

      ·        перед началом выполнения (\"Выполняется расчет. Пожалуйста, подождите…\")

      \n

      ·        в процессе выполнения (если есть возможность)

      \n

      ·        при завершении (\"Расчет выполнен\")

      \n

       

      \n

      4.2. Состояние используется для длительных операций, состоящих из некоторого числа более мелких операций.
      Например, при переносе файлов с жесткого диска в информационную базу можно выводить состояние для каждого переносимого файла:

      \n

       

      \n

      \n

       

      \n

      См. также: Длительные операции, Запись событий в историю работы пользователя

      \n

       

      \n

       

      \n

       

      \n

      5. Предупреждение

      \n

       

      \n

      5.1. Предупреждение рекомендуется использовать только в тех случаях, когда необходимо прервать работу пользователя, чтобы он ознакомился с некоторой информацией. При этом для возобновления работы пользователю не нужно принимать решений.

      \n

       

      \n

      5.2. Не следует использовать предупреждение для информирования о начале выполнения длительных обработок. Такое сообщения следует выдавать непосредственно в форме обработки.

      5.3. В тексте предупреждения следует привести законченные пояснения о последующих действиях и их последствиях.

      \n

      Например, пользователь пытается заполнить цены товаров в табличной части \"Товары\" документа «Заказ клиента». Программа выдает предупреждение о невозможности выполнения этого действия:

      \n

       

      \n

      \n

       

      \n

       

      \n

      6. Вопросы в сообщениях

      \n

       

      \n

      6.1. Рекомендуется использовать в тех случаях, когда необходимо, чтобы пользователь принял решение, например, о продолжении начатой операции.

      \n

       

      \n

      6.2. Вопросы рекомендуется выдавать перед выполнением:

      \n

      ·         действий, результаты которых отменить потом невозможно

      \n

      ·         потенциально опасных для данных пользователя действий

      \n

      ·         массовой обработки информационной базы

      \n

      ·         длительных процедур

      \n

       

      \n

      6.3. Ответами на вопрос должны выступать глаголы, обозначающие последующие действия.

      \n

      Например:

      \n

       

      \n

      \n

       

      \n

      6.4.  В сообщениях-вопросах кнопкой по умолчанию должна являться та кнопка, выбор которой наиболее безопасен для данных пользователя.
      Например, при сохранении файла кнопкой по умолчанию является \"Сохранить\":

      \n

       

      \n

      \n

       

      \n

      ВАЖНО: Чаще всего в ОС Windows кнопкой по умолчанию является первая (самая левая) кнопка. Прибегать к изменению кнопки по умолчанию рекомендуется только в исключительных ситуациях.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1224", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Превышена максимально допустимая ширина формы 1256.", +"Description": "

      Размеры формы

      #std505

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      Формы объектов метаданных типовых конфигураций разрабатываются в расчете на следующие условия применения: 

      \n
        \n
      • разрешение экрана 1280х768;  \n
      • окно 1С:Предприятия растянуто на весь экран;  \n
      • включено главное меню;  \n
      • включена одна строка панелей инструментов;  \n
      • включена панель окон;  \n
      • включена панель состояния.
      \n

      Исходя из этого максимальными размерами формы должны быть:

      \n
        \n
      • ширина - 1256 точек; \n
      • высота – 580 точек.
      \n

      Рекомендуется устанавливать оптимальные для работы пользователя размеры формы не превышая при этом приведенные размеры. Для форм, где присутствуют панели с закладками, ширину формы рекомендуется делать такой, чтобы заголовки всех закладок без сокращений были одновременно видны в форме.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1225", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Превышена максимально допустимая высота формы 580.", +"Description": "

      Размеры формы

      #std505

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      Формы объектов метаданных типовых конфигураций разрабатываются в расчете на следующие условия применения: 

      \n
        \n
      • разрешение экрана 1280х768;  \n
      • окно 1С:Предприятия растянуто на весь экран;  \n
      • включено главное меню;  \n
      • включена одна строка панелей инструментов;  \n
      • включена панель окон;  \n
      • включена панель состояния.
      \n

      Исходя из этого максимальными размерами формы должны быть:

      \n
        \n
      • ширина - 1256 точек; \n
      • высота – 580 точек.
      \n

      Рекомендуется устанавливать оптимальные для работы пользователя размеры формы не превышая при этом приведенные размеры. Для форм, где присутствуют панели с закладками, ширину формы рекомендуется делать такой, чтобы заголовки всех закладок без сокращений были одновременно видны в форме.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "123", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обращение к полям регистратора.", +"Description": "

      Самодостаточность регистров

      #std477

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      При разработке структуры регистров необходимо придерживаться правила, что регистр должен быть логически независим от регистраторов. Любая логика, опирающаяся или анализирующая данные регистра, а также любые отчеты по этому регистру не должны обращаться к полям регистратора, им должно быть достаточно данных самого регистра.

      \n

      Обращение к полям регистратора \"через точку\" приводит к неявному соединению с дополнительными таблицами. Кроме того, в распределенной информационной базе регистратора может и не быть, если движения в регистрах мигрируют между узлами, а регистраторы - нет.

      \n

      См. также

      \n\n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "1238", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не заполнена всплывающая подсказка в шапке колонки табличного поля.", +"Description": "

      Подсказки

      #std506

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      С целью пояснить назначение элемента управления ему назначается подсказка. Подсказка должна быть лаконичной, длина текста подсказки не должна превышать 8 слов. Заполнение подсказки обязательно.

      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1239", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Для полей ввода с установленным флагом \"Автоотметка незаполненного\", необходимо устанавливать флаг \"Автовыбор незаполненного\".", +"Description": "

      Использование флагов \"Автовыбор незаполненного\" и \"Автоотметка незаполненного\"

      #std507

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      Для полей ввода, необходимо устанавливать флаг Автовыбор незаполненного, если установлен флаг Автоотметка незаполненного.
      При этом свойство Режим выбора незаполненного устанавливается в значение При нажатии Enter.

      \n

      Это относится в равной степени как к элементам управления, которые располагаются непосредственно в форме, так и к тем, которые принадлежат колонке табличного поля.

      \n

      Исключение составляют поля ввода, в которых вводится число или дата. Для таких полей использование флага Автовыбор незаполненного определяется логикой работы.

      \n

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1240", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Колонки с заведомо известной требуемой шириной не должны изменять размер.", +"Description": "

      Изменения размера колонки табличного поля

      #std504

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      Для колонок табличных полей свойство ИзменениеРазмераКолонки устанавливается по следующим правилам.

      \n

      Колонке разрешается изменение размера, когда длина представления данных колонки заранее не известна или когда длина данных настолько большая, что ширину колонки по умолчанию устанавливают заведомо меньше требуемой. Например, разрешается изменять размер колонки, в которой отображаются ссылочные значения, строки неограниченной длины и т.п.

      \n

      Колонке не разрешается изменять размер, когда длина представления данных известна и может быть установлена при разработке формы. Например, не разрешается изменять размер колонок отображающих даты, числа, булевы значения. Исключением являются колонки, в которых отображается иерархия. Для таких колонок изменение размера запрещать нельзя.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1241", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "У элемента формы неверное имя.", +"Description": "

      Имя элемента управления

      #std503

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      1. Для элементов управления с непустыми данными имя элемента управления должно совпадать с данными.

      \n

      2. Для элементов управления с пустыми данными, но непустыми данными флажка имя элемента управления должно совпадать с данными флажка.

      \n

      3. Если данные (данные флажка) указаны как путь через точку, тогда имя элемента управления образуется из имени данных (данных флажка) исключая точки.

      \n

      4. В случаях когда нет или не указаны данные и данные флажка, имя элемента формы составляется из названия типа элемента управления и краткой расшифровки, поясняющей назначение элемента, например, ПолеВыбораУсловияОтбора.

      \n

      5. Если в форме в соответствии с правилом для нескольких элементов управления образуются одинаковые имена, один из элементов управления называется по правилу, а имена остальных образуются из имени по правилу с добавлением цифры, последовательно, начиная с \"1\". Например, если поле ввода с данными Номер и подпись к нему отображаются на нескольких страницах панели в форме, то на разных страницах их нужно называть так:

      \n
        \n
      • Номер, НадписьНомер; \n
      • Номер1, НадписьНомер1; \n
      • Номер2, НадписьНомер2; \n
      • Номер3, НадписьНомер3; \n
      • и т.д.
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1242", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Отсутствует комментарий к экспортной процедуре (функции).", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1243", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует или неверно описана секция \"Описание\" в комментарии к экспортной процедуре (функции).", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1244", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Обращение к несуществующему объекту метаданных.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1245", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Общий модуль, доступный на сервере и на клиенте, должен именоваться с постфиксом \"КлиентСервер\".", +"Description": "

      Правила создания общих модулей

      #std469

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

      \n

      1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
      (обычное приложение)
      Клиент
      (управляемое приложение)
      1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

       

      2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

      +

      \n

      +

      \n

       

      \n

       

      3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

       

      \n

       

      \n

       

      \n

      +

      \n

      +

      4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

      +

      \n

      \n

      2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
      Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

      \n
        \n
      • Сервер (флажок Вызов сервера сброшен), \n
      • Клиент (обычное приложение), \n
      • Внешнее соединение
      \n

      В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

      \n
        \n
      • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
      • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
      \n

      Серверные общие модули называются по общим правилам именования объектов метаданных.
      Например: РаботаСФайлами, ОбщегоНазначения

      \n

      В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
      Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

      \n

      2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
      Такие процедуры и функции размещаются в общих модулях с признаком:

      \n
        \n
      • Сервер (флажок Вызов сервера установлен)
      \n

      Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
      Например: РаботаСФайламиВызовСервера, CommonServerCall

      \n

      Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

      \n
      \n

      См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

      \n

      2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Клиент (обычное приложение)
      \n

      Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

      \n

      Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
      Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

      \n
      \n

      См. также: минимизация кода, выполняемого на клиенте

      \n

      2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Сервер (флажок Вызов сервера сброшен) \n
      • Клиент (обычное приложение) \n
      • Внешнее соединение
      \n

      Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
      Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

      \n

      В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

      \n
      \n

      Подробнее см.: Использование директив компиляции и инструкций препроцессора

      \n

      Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

      \n

      3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

      \n

      Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

      \n

      3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

      \n

      3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
      Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

      \n

      3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
      Например: РаботаСФайламиПолныеПрава

      \n

      3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
      Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

      \n

      3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
      Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

      \n
      \n

      См. также: Переопределяемые и поставляемые объекты библиотеки

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1248", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Ключевое слово написано не канонически.", +"Description": "

      Общие требования к построению конструкций встроенного языка

      #std441

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В конструкциях встроенного языка ключевые слова пишутся канонически (как в документации или Синтакс-помощнике).
      Правильно:

      \n

      КонецЕсли

      \n

      Неправильно:

      \n

      конецЕсли, КОНЕЦЕСЛИ, конецесли, Конецесли.

      \n

      2. При следовании друг за другом нескольких операторов присваивания, допускается выравнивать их следующим образом:

      \n

      ДиалогВыбора.ПолноеИмяФайла = ИмяФайла;
      ДиалогВыбора.Каталог        = ИмяПути;
      ДиалогВыбора.Заголовок      = НСтр(\"ru = 'Выберите файл со списком запросов'\");
      ДиалогВыбора.Фильтр         = НСтр(\"ru = 'Файлы запросов (*.sel)|*.sel|Все файлы (*.*)|*.*'\");
      ДиалогВыбора.Расширение     = \"sel\";

      \n

      При этом не следует выравнивать операторы одинаково по всему модулю - рекомендуется делать выравнивание только для операторов, расположенных рядом.

      3. Составные логические выражения в ЕслиКонецЕсли переносятся согласно правилам переноса выражений.

      \n

      4. Логические выражения и логические значения (например, результат функции, возвращающей логическое значение, переменные типа Булево и пр.) не следует проверять путем сравнения с литералами Истина и Ложь.
      Правильно:

      \n

      Если ЭтоНовый() Тогда

      \n

      Неправильно:

      \n

      Если ЭтоНовый() = Истина Тогда

      \n

      5. В тех случаях, когда требуется сравнивать результаты каких-либо выражений, следует предварительно присваивать результаты этих выражений промежуточным переменным, и сравнивать уже сами эти переменные.
      Правильно:

      \n

      Ответ = Вопрос(НСтр(\"ru = 'Данные еще не записаны. Записать?'\"), РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
      Если Ответ = КодВозвратаДиалога.Да Тогда
        Записать();
      Иначе
        Возврат;
      КонецЕсли;

      \n

      Неправильно:

      \n

      Если Вопрос(НСтр(\"ru = 'Данные еще не записаны. Записать?'\"), РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да) = КодВозвратаДиалога.Да Тогда
        Записать();
      Иначе
        Возврат;
      КонецЕсли;

      \n

      6. Необходимо использовать системные наборы значений везде, где возможно их применить, например, вместо Символ(10) следует использовать Символы.ПС.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 5 +}, +{ +"Code": "125", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Общий модуль недопустимого типа.", +"Description": "

      Правила создания общих модулей

      #std469

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

      \n

      1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
      (обычное приложение)
      Клиент
      (управляемое приложение)
      1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

       

      2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

      +

      \n

      +

      \n

       

      \n

       

      3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

       

      \n

       

      \n

       

      \n

      +

      \n

      +

      4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

      +

      \n

      \n

      2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
      Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

      \n
        \n
      • Сервер (флажок Вызов сервера сброшен), \n
      • Клиент (обычное приложение), \n
      • Внешнее соединение
      \n

      В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

      \n
        \n
      • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
      • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
      \n

      Серверные общие модули называются по общим правилам именования объектов метаданных.
      Например: РаботаСФайлами, ОбщегоНазначения

      \n

      В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
      Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

      \n

      2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
      Такие процедуры и функции размещаются в общих модулях с признаком:

      \n
        \n
      • Сервер (флажок Вызов сервера установлен)
      \n

      Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
      Например: РаботаСФайламиВызовСервера, CommonServerCall

      \n

      Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

      \n
      \n

      См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

      \n

      2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Клиент (обычное приложение)
      \n

      Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

      \n

      Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
      Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

      \n
      \n

      См. также: минимизация кода, выполняемого на клиенте

      \n

      2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Сервер (флажок Вызов сервера сброшен) \n
      • Клиент (обычное приложение) \n
      • Внешнее соединение
      \n

      Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
      Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

      \n

      В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

      \n
      \n

      Подробнее см.: Использование директив компиляции и инструкций препроцессора

      \n

      Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

      \n

      3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

      \n

      Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

      \n

      3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

      \n

      3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
      Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

      \n

      3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
      Например: РаботаСФайламиПолныеПрава

      \n

      3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
      Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

      \n

      3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
      Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

      \n
      \n

      См. также: Переопределяемые и поставляемые объекты библиотеки

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1297", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Строка не локализована. Возможно, она видна пользователю.", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n\n\n\n

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1298", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Нарушен синтаксис описания локализованной строки. Должен быть \"НСтр(\"ru='...'\")\" или \"NStr(\"en='...'\")\".", +"Description": "

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n\n\n\n

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1299", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Локализуемая строка начинается или заканчивается непечатаемым символом (например: пробел, таб, перенос).", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n\n\n\n

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1300", +"Type": "BUG", +"Severity": "MINOR", +"Name": "В тексте запроса находится строковый литерал.", +"Description": "

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1317", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Для объекта метаданных назначено несколько отложенных обработчиков обновления в последовательном режиме.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
      \n

      Отложенное обновление данных

      \n

      Область применения: управляемое приложение, обычное приложение.

      \n

      Действует для конфигураций на базе Библиотеки стандартных подсистем.
      Содержит уточнения к требованиям других стандартов.
      См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
      Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

      \n

      1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

      \n

      Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

      \n

      Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

      \n
        \n
      • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
      • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
      \n

      Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

      \n

      2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

      \n

      В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

      \n

      3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

      \n

      В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

      \n

      Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

      \n

      Например:

      \n

      Обработчик = Обработчикиобавить();
      Обработчик.Версия = \"1.2.3.4\";
      Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
      Обработчик.РежимВыполнения = \"Отложенно\";
      Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
      Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

      \n

      4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
      что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
      Например:

      \n
        \n
      • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
      • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
      • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
      • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
      \n

      5. Синтаксис процедуры-обработчика отложенного обновления:

      \n

      Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

      \n

      где Параметры – Структура со свойствами:

      \n
        \n
      • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
      • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
          \n
        • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
        • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
      \n

      (*) Примечание: актуально для версий БСП 2.3.1 и выше.

      \n

      6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
      Также рекомендуется начинать обработку с самых \"свежих\" данных.
      Например:

      \n

       Запрос = Новый Запрос;
       Запросекст = 
       \"ВЫБРАТЬ ПЕРВЫЕ 1000
       | ЗаказПокупателясылка
       |ИЗ
       | Документ.ЗаказПокупателя КАК ЗаказПокупателя
       |ГДЕ
       | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
       |
       |УПОРЯДОЧИТЬ ПО
       | ЗаказПокупателя.Дата УБЫВ\";

      \n

      7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

      \n

       ПараметрыбработкаЗавершена = Ложь;
       
       ПроблемныхОбъектов = 0;
       ОбъектовОбработано = 0;
       
       Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
        
        Попытка
         
         ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
         ОбъектовОбработано = ОбъектовОбработано + 1;
         
        Исключение
         // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
         ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
         
         ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
          НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
           |%2'\"), 
           ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
         ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
          Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
        КонецПопытки;
        
       КонецЦикла;
       
       Если ОбъектовОбработано = 0 Тогда
        ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
         НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
          ПроблемныхОбъектов);
        ВызватьИсключение ТекстСообщения;
       Иначе
        ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
         Метаданные.Документы._ДемоЗаказПокупателя,,
          НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
       КонецЕсли;

      \n

      При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

      \n

      8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

      \n

      Например:

      \n

      Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

       НачатьТранзакцию();
       Попытка
       
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
        ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
        Блокировка.Заблокировать();
        
        ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

      \n

        // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
        Если ДокументОбъект = Неопределено Тогда
         ОтменитьТранзакцию();
         Возврат;
        КонецЕсли;
        Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
         ОтменитьТранзакцию();
         Возврат;
        КонецЕсли;
        
        // Обрабатываем документ
        // ...
        
        ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
        
        ЗафиксироватьТранзакцию();
       Исключение
        ОтменитьТранзакцию();
        ВызватьИсключение;
       КонецПопытки;

      \n

      КонецПроцедуры

      \n

      9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

      \n

      10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

      \n
        \n
      • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
      • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
      \n

      В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

      \n

      11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

      \n

      С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

      \n

      Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

      \n

      Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

      \n

      См. также

      \n\n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1318", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Отложенный обработчик обновления в последовательном режиме для объекта одной подсистемы обрабатывает данные другой подсистемы.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
      \n

      Отложенное обновление данных

      \n

      Область применения: управляемое приложение, обычное приложение.

      \n

      Действует для конфигураций на базе Библиотеки стандартных подсистем.
      Содержит уточнения к требованиям других стандартов.
      См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
      Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

      \n

      1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

      \n

      Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

      \n

      Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

      \n
        \n
      • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
      • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
      \n

      Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

      \n

      2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

      \n

      В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

      \n

      3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

      \n

      В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

      \n

      Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

      \n

      Например:

      \n

      Обработчик = Обработчикиобавить();
      Обработчик.Версия = \"1.2.3.4\";
      Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
      Обработчик.РежимВыполнения = \"Отложенно\";
      Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
      Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

      \n

      4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
      что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
      Например:

      \n
        \n
      • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
      • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
      • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
      • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
      \n

      5. Синтаксис процедуры-обработчика отложенного обновления:

      \n

      Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

      \n

      где Параметры – Структура со свойствами:

      \n
        \n
      • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
      • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
          \n
        • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
        • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
      \n

      (*) Примечание: актуально для версий БСП 2.3.1 и выше.

      \n

      6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
      Также рекомендуется начинать обработку с самых \"свежих\" данных.
      Например:

      \n

       Запрос = Новый Запрос;
       Запросекст = 
       \"ВЫБРАТЬ ПЕРВЫЕ 1000
       | ЗаказПокупателясылка
       |ИЗ
       | Документ.ЗаказПокупателя КАК ЗаказПокупателя
       |ГДЕ
       | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
       |
       |УПОРЯДОЧИТЬ ПО
       | ЗаказПокупателя.Дата УБЫВ\";

      \n

      7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

      \n

       ПараметрыбработкаЗавершена = Ложь;
       
       ПроблемныхОбъектов = 0;
       ОбъектовОбработано = 0;
       
       Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
        
        Попытка
         
         ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
         ОбъектовОбработано = ОбъектовОбработано + 1;
         
        Исключение
         // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
         ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
         
         ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
          НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
           |%2'\"), 
           ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
         ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
          Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
        КонецПопытки;
        
       КонецЦикла;
       
       Если ОбъектовОбработано = 0 Тогда
        ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
         НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
          ПроблемныхОбъектов);
        ВызватьИсключение ТекстСообщения;
       Иначе
        ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
         Метаданные.Документы._ДемоЗаказПокупателя,,
          НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
       КонецЕсли;

      \n

      При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

      \n

      8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

      \n

      Например:

      \n

      Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

       НачатьТранзакцию();
       Попытка
       
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
        ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
        Блокировка.Заблокировать();
        
        ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

      \n

        // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
        Если ДокументОбъект = Неопределено Тогда
         ОтменитьТранзакцию();
         Возврат;
        КонецЕсли;
        Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
         ОтменитьТранзакцию();
         Возврат;
        КонецЕсли;
        
        // Обрабатываем документ
        // ...
        
        ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
        
        ЗафиксироватьТранзакцию();
       Исключение
        ОтменитьТранзакцию();
        ВызватьИсключение;
       КонецПопытки;

      \n

      КонецПроцедуры

      \n

      9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

      \n

      10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

      \n
        \n
      • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
      • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
      \n

      В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

      \n

      11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

      \n

      С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

      \n

      Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

      \n

      Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

      \n

      См. также

      \n\n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1319", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "После инициализации блокировки отсутствует вызов \"Заблокировать()\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      \n\n\n

      Перехват исключений в коде

      #std499

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В общем случае не рекомендуется перехватывать исключения. В частности не нужно перехватывать исключения только ради выдачи сообщения об ошибке. Необработанное исключение в любом случае будет выдано пользователю в виде сообщения об ошибке (а также будет записано в журнал регистрации для администратора, если исключение возникло на сервере).

      \n

      2. Тем не менее, необходимость перехвата исключений в коде все же возникает. Например, для того чтобы уточнить текст ошибки, дополнив его прикладной, понятной конечному пользователю, информацией. Однако при этом необходимо фиксировать причину ошибки в журнале регистрации для того, чтобы системный администратор имел возможность выполнить диагностику проблемы и при необходимости передать информацию об ошибке в службу технической поддержки.

      \n

      При этом рекомендуется записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю.

      \n

      3. Частные случаи некорректного использования и перехвата исключений.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      3.1. Если имеется некоторая серверная бизнес-логика, которая вызывается с клиента при интерактивной работе пользователя:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то неправильно маскировать от пользователя и администратора исходную проблему:

      \n

      // на клиенте
      Попытка
          ВыполнитьОперацию();
      Исключение
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена.'\"));
      КонецПопытки;

      \n

      Правильно записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
        Попытка
          // код, приводящий к вызову исключения
          ....
        Исключение
          // Запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
          ВызватьИсключение;
        КонецПопытки;
      КонецПроцедуры

      \n

      и тогда на клиенте:

      \n

      Попытка
          ВыполнитьОперацию();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
      КонецПопытки;

      \n

      3.2. Не следует анализировать текст исключений с целью интерпретации причины ошибки. Текст исключения может меняться в зависимости от локализации. В условиях отсутствия штатных средств (например, типизированных исключений), следует выдавать пользователю тексты исключений «как есть». Для понятности, его можно дополнить пояснением возможных причин.
      Например:

      \n

      Попытка
          ЗагрузитьФайлИзИнтернета(...);
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ТекстСообщения = НСтр(\"ru = 'Не удалось загрузить файл:'\") + Символы.ПС + ТекстСообщения + Символы.ПС + НСтр(\"ru = 'Возможные причины:
      • Нет подключения к Интернету;
      • На веб-узле возникли неполадки;
      • Брандмауэр или другое промежуточное ПО (антивирусы и т.п.) блокируют попытки программы подключиться к Интернету;
      • Подключение к Интернету выполняется через прокси-сервер, но его параметры не заданы в программе.'\");
          ПоказатьПредупреждение(,ТекстСообщения);
      КонецПопытки;

      \n

      В тех случаях, когда анализ типов исключений критически важен для корректной работы бизнес-логики, следует отказаться от исключений и использовать коды ошибок (коды возврата). При этом недопустимо использовать числовые коды ошибок, т.к. код становится нечитаемым:

      \n

      КодОшибки = ЗагрузитьФайлИзИнтернета(...);
      Если КодОшибки = 12345 Тогда
      ...
      ИначеЕсли ...

      \n

      правильно применять строковые литералы (например, \"Успешно\", \"НетМестаНаДиске\", \"Отменено\" и т.п.):

      \n

      РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(...);
      Если РезультатЗагрузки = \"Успешно\" Тогда
      ...
      ИначеЕсли ...

      \n

      Строковые литералы кодов ошибок не локализуются.

      \n

      Исключение составляют случаи работы с веб-сервисами и другими внешними системами, где коды ошибок не доступны, а результат работы транслируется в вызывающий код прикладной конфигурации в виде исключений.

      \n

      3.3. Если имеется некоторая клиентская бизнес-логика (код выполняется полностью на клиенте):

      \n

      &НаКлиенте
      Процедура СоздатьФайлНаДиске()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то рекомендуется делать дополнительный серверный вызов для протоколирования неудачного результата операции в журнал регистрации:

      \n

      Попытка
          // клиентский код, приводящий к вызову исключения
          СоздатьФайлНаДиске();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
          ЗаписатьОшибкуРаботыСФайлами(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
      КонецПопытки;

      \n

      &НаСервереБезКонтекста
      Процедура ЗаписатьОшибкуРаботыСФайлами(...)
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки);
      КонецПроцедуры

      \n

      3.4. Недопустимо перехватывать любые исключения, бесследно для системного администратора:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение // перехват любых исключений
      КонецПопытки;

      \n

      Как правило, подобная конструкция скрывает реальную проблему, которую впоследствии невозможно диагностировать.
      Правильно:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение
          // Пояснение причин перехвата всех исключений \"незаметно\" от пользователя.
          // ....
          // И запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
      КонецПопытки;

      \n

      См. также Доступ к файловой системе из кода конфигурации, удаление временных файлов

      \n

      3.5. Недопустимо делать проверки наличия у объекта реквизитов, методов, макетов и т.п., используя для этого исключения, т.к. это может привести к сложно диагностируемым ошибкам, а также затрудняет отладку в режиме «Останавливаться по ошибке».
      Вместо перехвата исключений в этом случае рекомендуется:

      \n
        \n
      • использовать механизмы работы с метаданными, чтобы явным образом проверять наличие или отсутствие реквизита (макета и т.п.); \n
      • если различия связаны с особенностями встраивания библиотек – описывать особенности явным образом в переопределяемых модулях (см. Переопределяемые и поставляемые объекты); \n
      • пересмотреть логику работы методов, использующих перехват исключений. Например, можно предусмотреть параметры, которые определяются в вызывающем коде и указывают нужно или нет обращаться к какому-либо методу или свойству объекта.
      \n

      Например, неправильно:

      \n

      Попытка
       КонтекстЭДОСервер.ПолучитьМакет(\"КомпонентаОбмена\");
       ПутьВК = КонтекстЭДОСервер.ПутьКОбъекту +  \".Макет.КомпонентаОбмена\";
      Исключение
      КонецПопытки;

      \n

      Правильно:

      \n

      МакетКомпонентыОбмена = КонтекстЭДОСервер.Метаданные().Макеты.Найти(\"КомпонентаОбмена\");
      Если МакетКомпонентыОбмена <> Неопределено Тогда
       ПутьКМакету = КомпонентаОбмена.ПолноеИмя()
      КонецЕсли;

      \n

      3.6. Порядок обработки исключений при использовании транзакций описан в стандарте Транзакции: правила использования.

      \n

      3.7. Неправильно использовать исключения для приведения значения к типу. Для таких операций необходимо использовать возможности объекта ОписаниеТипов.

      \n

      Например, неправильно:

      \n

      Попытка
       КоличествоДнейРазрешения = Число(Значение);
      Исключение
       КоличествоДнейРазрешения = 0; // значение по умолчанию
      КонецПопытки;

      \n

      Правильно:

      \n

      ОписаниеТипа = Новый ОписаниеТипов(\"Число\");
      КоличествоДнейРазрешения = ОписаниеТипа.ПривестиЗначение(Значение);

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "132", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не верно установлена текущая дата.", +"Description": "

      Работа в разных часовых поясах

      #std643

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Конфигурации должны быть рассчитаны на работу в условиях, когда часовой пояс на серверном компьютере не совпадает с реальным часовым поясом пользователей информационной базы. Например, с сервером, расположенным в Москве, работают сотрудники компании из Владивостока, и при этом все операции в системе должны выполняться по местному времени (Владивостока).

      \n

      Такой сценарий работы часто востребован в клиент-серверных информационных базах и в прикладных решениях в модели сервиса (SaaS).

      \n

      2.1. Во всех серверных процедурах и функциях вместо функции ТекущаяДата, которая возвращает дату и время серверного компьютера, следует использовать функцию ТекущаяДатаСеанса, которая приводит время сервера к часовому поясу пользовательского сеанса.

      \n

      2.2. В тех случаях, когда требуется «универсальная» отметка времени, не зависящая от часового пояса текущего сеанса пользователя, в контексте которого выполняется серверный вызов, следует использовать функцию УниверсальноеВремя. Например, для определения момента перезаполнения закешированных данных, для получения времени последнего выполнения фонового задания и т.п.

      \n

      2.3. При использовании методов платформы, возвращающих локальную дату серверного компьютера, следует приводить ее либо к универсальному времени, либо к времени пользовательского сеанса. Например:

      \n

      ДатаАктуальностиУниверсальная = УниверсальноеВремя(ПолнотекстовыйПоиск.ДатаАктуальности());
      ДатаАктуальности = МестноеВремя(ДатаАктуальностиУниверсальная, ЧасовойПоясСеанса());

      \n

      3.1. В клиентском коде использование функции ТекущаяДата также недопустимо. Это требование обусловлено тем, что текущее время, вычисленное в клиентском и серверном коде, не должно различаться.

      \n

      Например, с сервером, расположенным в Москве, работают пользователи из Киева. Функция ТекущаяДата для клиентского компьютера возвращает 10:00, а для сервера – 11:00. В то же время, функция ТекущаяДатаСеанса вернет на сервере 10:00, если в информационной базе установлено киевское время (с помощью метода УстановитьЧасовойПоясИнформационнойБазы).

      \n

      Как правило, вместо вызова функции ТекущаяДата на клиенте необходимо 

      \n
        \n
      • передавать с сервера на клиент время и дату, приведенную к часовому поясу пользовательского сеанса; \n
      • при работе с документами на клиенте, использовать дату документа.
      \n

      Рассмотрим типовые случаи на примерах.

      \n

      3.2. В алгоритме закрытия месяца с клиента на сервер передается дата, по которой далее определяется, какой месяц будет закрываться.

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
       ТекущиеДанные = Элементы.Список.ТекущиеДанные;
       Если ТекущиеДанные = Неопределено Тогда
        ТекДата  = ТекущаяДата();  // вызов ТекущаяДата() на клиенте
       Иначе
        ТекДата  = ТекущиеДанные.Дата;
       КонецЕсли;
       ПараметрыФормы = Новый Структура;
       ПараметрыФормы.Вставить(\"ПериодРегистрации\", ТекДата);
       ОткрытьФорму(\"Обработка.ЗакрытиеМесяца.Форма.Форма\", ПараметрыФормы, ЭтотОбъект);

      \n

      а затем в форме обработки:

      \n

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       ЗаполнитьЗначенияСвойств(Объект, Параметры);
       Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДата());
       КонецЕсли;

      \n

      Правильно

      \n

      перенести получение текущей даты на сервер:

      \n

      &НаКлиенте
      Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
       ТекущиеДанные = Элементы.Список.ТекущиеДанные;
       Если ТекущиеДанные = Неопределено Тогда
        ТекДата  = Неопределено; // нет вызова ТекущаяДата() на клиенте
       Иначе
        ТекДата  = ТекущиеДанные.Дата;
       КонецЕсли;
       ПараметрыФормы = Новый Структура;
       ПараметрыФормы.Вставить(\"ПериодРегистрации\", ТекДата);
       ОткрытьФорму(\"Обработка.ЗакрытиеМесяца.Форма.Форма\", ПараметрыФормы, ЭтотОбъект);

      \n

      и в форме обработки использовать для этого функцию ТекущаяДатаСеанса:

      \n

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       ЗаполнитьЗначенияСвойств(Объект, Параметры);
       Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДатаСеанса());
       КонецЕсли;

      \n

      3.3. При работе с документами следует рассмотреть возможность использования даты самого документа вместо текущей даты. Например, в реализации подбора номенклатуры в табличную часть документа, в форму подбора из клиентского кода передается дата расчетов для вывода цен и остатков на эту дату.

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура ПодборТовары(Команда)
       ПараметрыПодбора = Новый Структура;
       ДатаРасчетов = ?(НачалоДня(Объект.Дата) = НачалоДня(ТекущаяДата()),
        Неопределено, Объект.Дата); // вызов ТекущаяДата() на клиенте
       ПараметрыПодбора.Вставить(\"ДатаРасчетов\", ДатаРасчетов);
       ...
       ОткрытьФорму(\"Обработка.ПодборНоменклатуры.Форма.Форма\", ПараметрыПодбора,
        ЭтотОбъект, УникальныйИдентификатор);

      \n

      Правильно

      \n

      передавать на сервер дату документа, а вычисление даты расчетов выполнять на сервере:

      \n

      &НаКлиенте
      Процедура ПодборТовары(Команда)
       ПараметрыПодбора = Новый Структура;
       ПараметрыПодбора.Вставить(\"ДатаРасчетов\", Объект.Дата);
       ...
       ОткрытьФорму(\"Обработка.ПодборНоменклатуры.Форма.Форма\", ПараметрыПодбора,
        ЭтотОбъект, УникальныйИдентификатор);

      \n

      Другой пример. При подборе документов для зачета аванса в форме подбора устанавливается отбор по условию «дата документов аванса не больше переданной в форму».

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура ЗачетАвансовДокументАвансаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
       СтандартнаяОбработка = Ложь;
       ПараметрыФормы = Новый Структура;
        ПараметрыФормы.Вставить(\"КонецПериода\",                                   
      ?(ЗначениеЗаполнено(Параметры.Ключ), Объект.Дата - 1, КонецДня(ТекущаяДата()))); // вызов ТекущаяДата() на клиенте
       ...
        ОткрытьФорму(\"Документ.ДокументРасчетовСКонтрагентом.ФормаВыбора\",        
      ПараметрыФормы, Элемент);
      ...

      \n

      Правильно

      \n

      вычислять параметр КонецПериода по дате документа:

      \n

      &НаКлиенте
      Процедура ЗачетАвансовДокументАвансаНачалоВыбора(Элемент, ДанныеВыбора,
      СтандартнаяОбработка)
       СтандартнаяОбработка = Ложь;
       ПараметрыФормы = Новый Структура;
        ПараметрыФормы.Вставить(\"КонецПериода\", ?(ЗначениеЗаполнено(Параметры.Ключ),
        Объект.Дата - 1, КонецДня(Объект.Дата)));
       ...
        ОткрытьФорму(\"Документ.ДокументРасчетовСКонтрагентом.ФормаВыбора\", ПараметрыФормы, Элемент);

      \n

      3.4. В остальных случаях при использовании Библиотеки стандартных подсистем рекомендуется использовать функцию ДатаСеанса общего модуля ОбщегоНазначенияКлиент.

      \n

      4. Исключения из правил 2 и 3 возможны в отдельных, обоснованных случаях, когда требуется использовать действительно текущее время серверного компьютера. Такие исключения должны быть обоснованы в тексте комментария к вызову.

      \n

      5. Следует избегать в коде одной процедуры (функции) многократного обращения к функции ТекущаяДатаСеанса (ТекущаяДата), так как возвращаемые значения будут отличаться друг от друга.

      \n

      Неправильно

      \n

      ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
      ДатаСледующегоОповещения = РассчитатьДату() + ТекущаяДатаСеанса();

      \n

      Правильно

      \n

      использовать ранее рассчитанные дату и время:

      \n

      ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
      ДатаСледующегоОповещения = РассчитатьДату() + ДатаПоследнегоОповещения;

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1320", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Вызов \"Заблокировать()\" находится вне попытки.", +"Description": "

      Перехват исключений в коде

      #std499

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В общем случае не рекомендуется перехватывать исключения. В частности не нужно перехватывать исключения только ради выдачи сообщения об ошибке. Необработанное исключение в любом случае будет выдано пользователю в виде сообщения об ошибке (а также будет записано в журнал регистрации для администратора, если исключение возникло на сервере).

      \n

      2. Тем не менее, необходимость перехвата исключений в коде все же возникает. Например, для того чтобы уточнить текст ошибки, дополнив его прикладной, понятной конечному пользователю, информацией. Однако при этом необходимо фиксировать причину ошибки в журнале регистрации для того, чтобы системный администратор имел возможность выполнить диагностику проблемы и при необходимости передать информацию об ошибке в службу технической поддержки.

      \n

      При этом рекомендуется записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю.

      \n

      3. Частные случаи некорректного использования и перехвата исключений.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      3.1. Если имеется некоторая серверная бизнес-логика, которая вызывается с клиента при интерактивной работе пользователя:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то неправильно маскировать от пользователя и администратора исходную проблему:

      \n

      // на клиенте
      Попытка
          ВыполнитьОперацию();
      Исключение
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена.'\"));
      КонецПопытки;

      \n

      Правильно записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
        Попытка
          // код, приводящий к вызову исключения
          ....
        Исключение
          // Запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
          ВызватьИсключение;
        КонецПопытки;
      КонецПроцедуры

      \n

      и тогда на клиенте:

      \n

      Попытка
          ВыполнитьОперацию();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
      КонецПопытки;

      \n

      3.2. Не следует анализировать текст исключений с целью интерпретации причины ошибки. Текст исключения может меняться в зависимости от локализации. В условиях отсутствия штатных средств (например, типизированных исключений), следует выдавать пользователю тексты исключений «как есть». Для понятности, его можно дополнить пояснением возможных причин.
      Например:

      \n

      Попытка
          ЗагрузитьФайлИзИнтернета(...);
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ТекстСообщения = НСтр(\"ru = 'Не удалось загрузить файл:'\") + Символы.ПС + ТекстСообщения + Символы.ПС + НСтр(\"ru = 'Возможные причины:
      • Нет подключения к Интернету;
      • На веб-узле возникли неполадки;
      • Брандмауэр или другое промежуточное ПО (антивирусы и т.п.) блокируют попытки программы подключиться к Интернету;
      • Подключение к Интернету выполняется через прокси-сервер, но его параметры не заданы в программе.'\");
          ПоказатьПредупреждение(,ТекстСообщения);
      КонецПопытки;

      \n

      В тех случаях, когда анализ типов исключений критически важен для корректной работы бизнес-логики, следует отказаться от исключений и использовать коды ошибок (коды возврата). При этом недопустимо использовать числовые коды ошибок, т.к. код становится нечитаемым:

      \n

      КодОшибки = ЗагрузитьФайлИзИнтернета(...);
      Если КодОшибки = 12345 Тогда
      ...
      ИначеЕсли ...

      \n

      правильно применять строковые литералы (например, \"Успешно\", \"НетМестаНаДиске\", \"Отменено\" и т.п.):

      \n

      РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(...);
      Если РезультатЗагрузки = \"Успешно\" Тогда
      ...
      ИначеЕсли ...

      \n

      Строковые литералы кодов ошибок не локализуются.

      \n

      Исключение составляют случаи работы с веб-сервисами и другими внешними системами, где коды ошибок не доступны, а результат работы транслируется в вызывающий код прикладной конфигурации в виде исключений.

      \n

      3.3. Если имеется некоторая клиентская бизнес-логика (код выполняется полностью на клиенте):

      \n

      &НаКлиенте
      Процедура СоздатьФайлНаДиске()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то рекомендуется делать дополнительный серверный вызов для протоколирования неудачного результата операции в журнал регистрации:

      \n

      Попытка
          // клиентский код, приводящий к вызову исключения
          СоздатьФайлНаДиске();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
          ЗаписатьОшибкуРаботыСФайлами(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
      КонецПопытки;

      \n

      &НаСервереБезКонтекста
      Процедура ЗаписатьОшибкуРаботыСФайлами(...)
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки);
      КонецПроцедуры

      \n

      3.4. Недопустимо перехватывать любые исключения, бесследно для системного администратора:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение // перехват любых исключений
      КонецПопытки;

      \n

      Как правило, подобная конструкция скрывает реальную проблему, которую впоследствии невозможно диагностировать.
      Правильно:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение
          // Пояснение причин перехвата всех исключений \"незаметно\" от пользователя.
          // ....
          // И запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
      КонецПопытки;

      \n

      См. также Доступ к файловой системе из кода конфигурации, удаление временных файлов

      \n

      3.5. Недопустимо делать проверки наличия у объекта реквизитов, методов, макетов и т.п., используя для этого исключения, т.к. это может привести к сложно диагностируемым ошибкам, а также затрудняет отладку в режиме «Останавливаться по ошибке».
      Вместо перехвата исключений в этом случае рекомендуется:

      \n
        \n
      • использовать механизмы работы с метаданными, чтобы явным образом проверять наличие или отсутствие реквизита (макета и т.п.); \n
      • если различия связаны с особенностями встраивания библиотек – описывать особенности явным образом в переопределяемых модулях (см. Переопределяемые и поставляемые объекты); \n
      • пересмотреть логику работы методов, использующих перехват исключений. Например, можно предусмотреть параметры, которые определяются в вызывающем коде и указывают нужно или нет обращаться к какому-либо методу или свойству объекта.
      \n

      Например, неправильно:

      \n

      Попытка
       КонтекстЭДОСервер.ПолучитьМакет(\"КомпонентаОбмена\");
       ПутьВК = КонтекстЭДОСервер.ПутьКОбъекту +  \".Макет.КомпонентаОбмена\";
      Исключение
      КонецПопытки;

      \n

      Правильно:

      \n

      МакетКомпонентыОбмена = КонтекстЭДОСервер.Метаданные().Макеты.Найти(\"КомпонентаОбмена\");
      Если МакетКомпонентыОбмена <> Неопределено Тогда
       ПутьКМакету = КомпонентаОбмена.ПолноеИмя()
      КонецЕсли;

      \n

      3.6. Порядок обработки исключений при использовании транзакций описан в стандарте Транзакции: правила использования.

      \n

      3.7. Неправильно использовать исключения для приведения значения к типу. Для таких операций необходимо использовать возможности объекта ОписаниеТипов.

      \n

      Например, неправильно:

      \n

      Попытка
       КоличествоДнейРазрешения = Число(Значение);
      Исключение
       КоличествоДнейРазрешения = 0; // значение по умолчанию
      КонецПопытки;

      \n

      Правильно:

      \n

      ОписаниеТипа = Новый ОписаниеТипов(\"Число\");
      КоличествоДнейРазрешения = ОписаниеТипа.ПривестиЗначение(Значение);

      \n\n\n

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1324", +"Type": "VULNERABILITY", +"Severity": "MAJOR", +"Name": "Использован конструктор \"Новый ЗащищенноеСоединениеOpenSSL\".", +"Description": "

      Ограничение на выполнение «внешнего» кода

      #std669

      Область применения: управляемое приложение, обычное приложение.

      \n

      Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

      \n

      Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

      \n

      1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

      \n

      Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

      \n
        \n
      • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
      • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
      • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

      \n
        \n
      • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
      • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
      • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
      • для запуска внешних программ – см. Безопасность запуска приложений.
      \n

      При этом указанное в этом пункте требование будет выполнено.

      \n

      2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
      При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

      \n

      3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

      \n

      3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

      \n

      3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
      Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем

      \n
        \n
      • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
      • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
      \n

      4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

      \n

      \n
        \n
      • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
      • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
      • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
      • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

      \n

      5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
      В этом случае в конфигурации следует предусмотреть

      \n
        \n
      • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
      • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
      \n

      Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

      \n

      6. Безопасность внешних компонент.

      \n

      6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

      \n

      Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

      \n

      6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

      \n

      Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

      \n

      6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

      \n

      6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

      \n
        \n
      • ПодключитьВнешнююКомпоненту; \n
      • НачатьУстановкуВнешнейКомпоненты; \n
      • УстановитьВнешнююКомпоненту; \n
      • НачатьПодключениеВнешнейКомпоненты; \n
      • ЗагрузитьВнешнююКомпоненту.
      \n

      Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

      \n

      ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

      \n

      Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

      \n

      ОбщегоНазначения.ПодключитьКомпонентуИзМакета

      \n

      Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

      \n

      ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

      \n

      7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

      \n
        \n
      • использовать только надежные источники, к которым есть доверие; \n
      • выполнять передачу данных только по защищенным каналам связи.
      \n

      ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
      Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

      \n

      ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
      Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1326", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно установлено значение стиля", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1327", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует исключительная управляемая блокировка на записываемые (удаляемые) данные.", +"Description": "

      Блокировка данных объекта для редактирования из кода

      #std490

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).

      \n

      В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.

      \n

      При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных. В отличие от транзакционных блокировок данных, пессимистическая блокировка данных для редактирования предназначена для обеспечения конкурентной работы пользователей с объектами информационной базы 1С:Предприятия (элементами справочников, документами и т.д.) Подробнее о блокировке данных для редактирования см. документацию по платформе 1С:Предприятие 8.

      \n

      1.2. Для блокировки данных для редактирования из встроенного языка следует вызывать метод объектов Заблокировать или метод глобального контекста ЗаблокироватьДанныеДляРедактирования.

      \n

      Пример № 1. Требуется заблокировать объект и, если это удалось, модифицировать данные. В противном случае – проинформировать пользователя об отказе в выполнении операции с помощью сообщения вида:

      «Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено. Ошибка блокировки объекта. Объект уже заблокирован: компьютер: <имя компьютера>, пользователь: <имя пользователя>, сеанс: <номер сеанса>, начат: <дата и время>, приложение: <тип клиентского приложения>».

      \n

      ФайлОбъект = ДанныеФайла.Ссылка.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями; в случае блокировки -
      // вывести пользователю сообщение об исключении.
      ФайлОбъект.Заблокировать(); 
      // Затем изменить и записать объект
      ФайлОбъект.Редактирует = Справочники.Пользователи.ПустаяСсылка();
      ФайлОбъект.Записать();

      \n

      Аналогичным образом, можно воспользоваться методом глобального контекста ЗаблокироватьДанныеДляРедактирования:

      \n

      ФайлОбъект = ДанныеФайла.Ссылка.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями; в случае блокировки -
      // вывести пользователю сообщение об исключении.
      ЗаблокироватьДанныеДляРедактирования(ДанныеФайла.Ссылка); 
      // Затем изменить и записать объект
      ФайлОбъект.Редактирует = Справочники.Пользователи.ПустаяСсылка();
      ФайлОбъект.Записать();

      \n

      Пример № 2. Требуется пропустить обработку объекта, если он заблокирован для редактирования. При очередном вызове процедуры (например, из фонового или регламентного задания) будет предпринята повторная попытка изменения объекта.

      \n

      Объект = ТекущаяВерсия.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями
      УстановитьПолноеНаименование = Истина;
      Попытка
        ФайлОбъект.Заблокировать();
      Исключение
        // в случае блокировки - не выполнять изменение объекта
        УстановитьПолноеНаименование = Ложь;
        // записать предупреждение в журнал регистрации
        ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Фоновое обновление имен файлов'\", Метаданные.ОсновнойЯзык.КодЯзыка),
          УровеньЖурналаРегистрации.Предупреждение,, ФайлОбъект, ОписаниеОшибки());
      КонецПопытки;

      \n

      // Пропустить обработку объекта, если он заблокирован.
      Если УстановитьПолноеНаименование Тогда
        Объект.ПолноеНаименование = ПолноеНаименование;
        Объект.Записать();
      КонецЕсли; 

      \n

      1.3. При редактировании данных в формах, платформа 1С:Предприятие автоматически устанавливает блокировку объекта, указанного в качестве основного реквизита формы.

      \n

      2. Не следует проверять блокировку объектов для редактирования в следующих случаях:

      \n
        \n
      • при выполнении отдельных операций, имеющих по логике работы больший приоритет по сравнению с интерактивными действиями пользователя. Например, загрузка данных при обмене; \n
      • при действиях, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы.
      \n\n\n

      Ответственное чтение данных

      #std648

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Общие рекомендации по использованию транзакций при чтении данных

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.1. Если чтение данных из информационной базы должно быть ответственным, следует производить такое чтение в транзакции с предварительной установкой управляемых блокировок. В общем случае, ответственным следует считать любое чтение, на основе результатов которого производятся какие-либо изменения в информационной базе или принимаются решения.
      Например, ответственное чтение данных требуется в следующих случаях:

      \n
        \n
      • \n
        Чтение данных при проведении, для последующего формирования движений;
        \n
      • \n
        Чтение данных для последующей целостной передачи в другую систему, например в программы типа «Клиент банк»;
        \n
      • \n
        Выполнение групповой обработки объектов, при реструктуризации данных в обработчиках отложенного и оперативного обновления ИБ (*)

        * Примечание: перед модификацией ссылочных объектов, обычно, следует устанавливать на них пессимистичные объектные блокировки.
      \n

      Неправильно:

      \n

      // 1. Прочитать регистр сведений
      Запрос = Новый Запрос(
        \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
        | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
        |ИЗ
        | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
        |ГДЕ
        | ЗаметкиПоПредмету.Предмет = &Предмет\");
      Запрос.УстановитьПараметр(\"Предмет\", ПредметЗаметок);
      Выборка = Запрос.Выполнить().Выбрать();
       
      КоличествоЗаметок = 0;
      Если Выборка.Следующий() Тогда
        КоличествоЗаметок = Выборка.КоличествоЗаметок;
      КонецЕсли;
       
      // 2. Записать в регистр сведений
      НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
      НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
      НоваяЗапись = НаборЗаписей.Добавить();
      НоваяЗапись.Предмет = ПредметЗаметок;
      НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
      НаборЗаписей.Записать();

      \n

      Правильно:

      \n

      // 1. Начать транзакцию для пакета из двух операций чтения и записи регистра
      НачатьТранзакцию();

      \n

      Попытка
        // 2. Установить исключительную блокировку на интересующий диапазон записей регистра,
        // для того чтобы гарантировать, что в момент записи количество заметок не изменилось с момента чтения в каком-либо другом сеансе.
        БлокировкаДанных = Новый БлокировкаДанных;
        ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"РегистрСведений.ЗаметкиПоПредмету\");
        ЭлементБлокировкиДанных.УстановитьЗначение(\"Предмет\", ПредметЗаметок);
        ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
        БлокировкаДанных.Заблокировать();
       
        // 3. Прочитать регистр сведений
        Запрос = Новый Запрос(
          \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
          | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
          |ИЗ
          | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
          |ГДЕ
          | ЗаметкиПоПредмету.Предмет = &Предмет\");
        Запрос.УстановитьПараметр(\"Предмет\", ПредметЗаметок);
       
        Выборка = Запрос.Выполнить().Выбрать();
       
        КоличествоЗаметок = 0;
        Если Выборка.Следующий() Тогда
          КоличествоЗаметок = Выборка.КоличествоЗаметок;
        КонецЕсли;
       
        // 4. Записать в регистр сведений
        НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
        НоваяЗапись = НаборЗаписей.Добавить();
        НоваяЗапись.Предмет = ПредметЗаметок;
        НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
        НаборЗаписей.Записать();
       
        ЗафиксироватьТранзакцию();
      Исключение
        // 5. Если при установке блокировки возникла исключительная ситуация из-за того, что регистр уже заблокирован в другом сеансе (или по другим причинам),
        // отменить транзакцию и записать сведения об ошибке в журнал регистрации.
        ОтменитьТранзакцию();
        ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Заметки'\", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение;
      КонецПопытки;

      \n

      В некоторых случаях, ответственное чтение не требуется в силу решаемой прикладной задачи, например:

      \n
        \n
      • Получение данных динамическими списками;  \n
      • Поиск данных; \n
      • Формирование большинства отчетов.
      \n

      В некоторых случаях, ответственное чтение не требуется, так как конкурентная работа с данными маловероятна или полностью исключена, например:

      \n
        \n
      • \n
        Обращение к условно постоянной информации. Например, чтение константы ВалютаРегламентированногоУчета или обращение к учетной политике;
        \n
      • \n
        Действия, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы;
        \n
      • \n
        Действия над данными, доступ к которым имеет только один пользователь, поэтому конкурентная работа с ними маловероятна или полностью исключена.
        Например, персональные данные, хранящиеся в «разрезе» пользователей;
        \n
      • \n
        Мобильное приложение, где конкурентная работа с данными маловероятна или полностью исключена.
      \n

      1.2. В большинстве случаев, при выполнении чтения в обработчиках событий связанных с модификацией данных, весь код обработчика выполняется в рамках системной транзакции, которая открыта платформой, и явно открывать новую транзакцию не требуется.

      \n

      Например, в системной транзакции выполняются обработчики модулей объектов и соответствующие им подписки на события:

      \n\n

      Подробнее – см. документацию к платформе 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      2. Выбор: исключительная или разделяемая блокировка

      \n

      2.1. Если в транзакции производится ответственное чтение данных с их последующим изменением, необходимо установить исключительную управляемую блокировку (до выполнения чтения). В противном случае возможно возникновение взаимоблокировки.

      \n

      Пример установки исключительной блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

      \n

      // 1. Установить исключительную блокировку для ответственного чтения объекта с целью его дальнейшего изменения
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Приказы\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказСсылка);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // можно не указывать, т.к. по умолчанию Исключительный
      Блокировка.Заблокировать();

      \n

      // 2. Получить объект для его дальнейшей модификации
      Объект = ПриказСсылка.ПолучитьОбъект();
      Если Объект = Неопределено Тогда // объект может быть уже удален в других сеансах
        Возврат;
      КонецЕсли;

      \n

      // 3. Выполнить блокировку объекта от изменения другими сеансами
      ЗаблокироватьДанныеДляРедактирования(ПриказСсылка);

      // 4. Записать измененный объект
      Объект.Реквизит = ...
      Объект.Записать();

      \n

      2.2. Если в транзакции производится ответственное чтение данных без их последующего изменения (например, для формирования движений), необходимо установить разделяемую блокировку на читаемые данные и исключительную блокировку на изменяемые данные.

      \n

      Пример установки разделяемой блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

      \n

      // 1. Установить разделяемую блокировку для ответственного чтения нескольких связанных объектов
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Приказы\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказСсылка);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
      Блокировка.Заблокировать();

      \n

      // 2. Прочитать первый объект - приказ
      ПриказОбъект = ПриказСсылка.ПолучитьОбъект();

      // 3. Прочитать второй объект – пользователя (автора приказа)
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Пользователи\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказОбъект.Автор);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
      Блокировка.Заблокировать();

      АвторПриказа = ПриказОбъект.Автор.ПолучитьОбъект();

      \n

       

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1328", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует разделяемая управляемая блокировка на читаемые данные.", +"Description": "

      Ответственное чтение данных

      #std648

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Общие рекомендации по использованию транзакций при чтении данных

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.1. Если чтение данных из информационной базы должно быть ответственным, следует производить такое чтение в транзакции с предварительной установкой управляемых блокировок. В общем случае, ответственным следует считать любое чтение, на основе результатов которого производятся какие-либо изменения в информационной базе или принимаются решения.
      Например, ответственное чтение данных требуется в следующих случаях:

      \n
        \n
      • \n
        Чтение данных при проведении, для последующего формирования движений;
        \n
      • \n
        Чтение данных для последующей целостной передачи в другую систему, например в программы типа «Клиент банк»;
        \n
      • \n
        Выполнение групповой обработки объектов, при реструктуризации данных в обработчиках отложенного и оперативного обновления ИБ (*)

        * Примечание: перед модификацией ссылочных объектов, обычно, следует устанавливать на них пессимистичные объектные блокировки.
      \n

      Неправильно:

      \n

      // 1. Прочитать регистр сведений
      Запрос = Новый Запрос(
        \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
        | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
        |ИЗ
        | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
        |ГДЕ
        | ЗаметкиПоПредмету.Предмет = &Предмет\");
      Запрос.УстановитьПараметр(\"Предмет\", ПредметЗаметок);
      Выборка = Запрос.Выполнить().Выбрать();
       
      КоличествоЗаметок = 0;
      Если Выборка.Следующий() Тогда
        КоличествоЗаметок = Выборка.КоличествоЗаметок;
      КонецЕсли;
       
      // 2. Записать в регистр сведений
      НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
      НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
      НоваяЗапись = НаборЗаписей.Добавить();
      НоваяЗапись.Предмет = ПредметЗаметок;
      НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
      НаборЗаписей.Записать();

      \n

      Правильно:

      \n

      // 1. Начать транзакцию для пакета из двух операций чтения и записи регистра
      НачатьТранзакцию();

      \n

      Попытка
        // 2. Установить исключительную блокировку на интересующий диапазон записей регистра,
        // для того чтобы гарантировать, что в момент записи количество заметок не изменилось с момента чтения в каком-либо другом сеансе.
        БлокировкаДанных = Новый БлокировкаДанных;
        ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"РегистрСведений.ЗаметкиПоПредмету\");
        ЭлементБлокировкиДанных.УстановитьЗначение(\"Предмет\", ПредметЗаметок);
        ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
        БлокировкаДанных.Заблокировать();
       
        // 3. Прочитать регистр сведений
        Запрос = Новый Запрос(
          \"ВЫБРАТЬ РАЗРЕШЕННЫЕ
          | ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
          |ИЗ
          | РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
          |ГДЕ
          | ЗаметкиПоПредмету.Предмет = &Предмет\");
        Запрос.УстановитьПараметр(\"Предмет\", ПредметЗаметок);
       
        Выборка = Запрос.Выполнить().Выбрать();
       
        КоличествоЗаметок = 0;
        Если Выборка.Следующий() Тогда
          КоличествоЗаметок = Выборка.КоличествоЗаметок;
        КонецЕсли;
       
        // 4. Записать в регистр сведений
        НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
        НоваяЗапись = НаборЗаписей.Добавить();
        НоваяЗапись.Предмет = ПредметЗаметок;
        НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
        НаборЗаписей.Записать();
       
        ЗафиксироватьТранзакцию();
      Исключение
        // 5. Если при установке блокировки возникла исключительная ситуация из-за того, что регистр уже заблокирован в другом сеансе (или по другим причинам),
        // отменить транзакцию и записать сведения об ошибке в журнал регистрации.
        ОтменитьТранзакцию();
        ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Заметки'\", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение;
      КонецПопытки;

      \n

      В некоторых случаях, ответственное чтение не требуется в силу решаемой прикладной задачи, например:

      \n
        \n
      • Получение данных динамическими списками;  \n
      • Поиск данных; \n
      • Формирование большинства отчетов.
      \n

      В некоторых случаях, ответственное чтение не требуется, так как конкурентная работа с данными маловероятна или полностью исключена, например:

      \n
        \n
      • \n
        Обращение к условно постоянной информации. Например, чтение константы ВалютаРегламентированногоУчета или обращение к учетной политике;
        \n
      • \n
        Действия, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы;
        \n
      • \n
        Действия над данными, доступ к которым имеет только один пользователь, поэтому конкурентная работа с ними маловероятна или полностью исключена.
        Например, персональные данные, хранящиеся в «разрезе» пользователей;
        \n
      • \n
        Мобильное приложение, где конкурентная работа с данными маловероятна или полностью исключена.
      \n

      1.2. В большинстве случаев, при выполнении чтения в обработчиках событий связанных с модификацией данных, весь код обработчика выполняется в рамках системной транзакции, которая открыта платформой, и явно открывать новую транзакцию не требуется.

      \n

      Например, в системной транзакции выполняются обработчики модулей объектов и соответствующие им подписки на события:

      \n\n

      Подробнее – см. документацию к платформе 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      2. Выбор: исключительная или разделяемая блокировка

      \n

      2.1. Если в транзакции производится ответственное чтение данных с их последующим изменением, необходимо установить исключительную управляемую блокировку (до выполнения чтения). В противном случае возможно возникновение взаимоблокировки.

      \n

      Пример установки исключительной блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

      \n

      // 1. Установить исключительную блокировку для ответственного чтения объекта с целью его дальнейшего изменения
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Приказы\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказСсылка);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // можно не указывать, т.к. по умолчанию Исключительный
      Блокировка.Заблокировать();

      \n

      // 2. Получить объект для его дальнейшей модификации
      Объект = ПриказСсылка.ПолучитьОбъект();
      Если Объект = Неопределено Тогда // объект может быть уже удален в других сеансах
        Возврат;
      КонецЕсли;

      \n

      // 3. Выполнить блокировку объекта от изменения другими сеансами
      ЗаблокироватьДанныеДляРедактирования(ПриказСсылка);

      // 4. Записать измененный объект
      Объект.Реквизит = ...
      Объект.Записать();

      \n

      2.2. Если в транзакции производится ответственное чтение данных без их последующего изменения (например, для формирования движений), необходимо установить разделяемую блокировку на читаемые данные и исключительную блокировку на изменяемые данные.

      \n

      Пример установки разделяемой блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

      \n

      // 1. Установить разделяемую блокировку для ответственного чтения нескольких связанных объектов
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Приказы\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказСсылка);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
      Блокировка.Заблокировать();

      \n

      // 2. Прочитать первый объект - приказ
      ПриказОбъект = ПриказСсылка.ПолучитьОбъект();

      // 3. Прочитать второй объект – пользователя (автора приказа)
      Блокировка = Новый БлокировкаДанных;
      ЭлементБлокировки = Блокировка.Добавить(\"Справочник.Пользователи\");
      ЭлементБлокировки.УстановитьЗначение(\"Ссылка\", ПриказОбъект.Автор);
      ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
      Блокировка.Заблокировать();

      АвторПриказа = ПриказОбъект.Автор.ПолучитьОбъект();

      \n

       

      \n

      См. также

      \n\n\n\n

      Блокировка данных объекта для редактирования из кода

      #std490

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).

      \n

      В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.

      \n

      При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных. В отличие от транзакционных блокировок данных, пессимистическая блокировка данных для редактирования предназначена для обеспечения конкурентной работы пользователей с объектами информационной базы 1С:Предприятия (элементами справочников, документами и т.д.) Подробнее о блокировке данных для редактирования см. документацию по платформе 1С:Предприятие 8.

      \n

      1.2. Для блокировки данных для редактирования из встроенного языка следует вызывать метод объектов Заблокировать или метод глобального контекста ЗаблокироватьДанныеДляРедактирования.

      \n

      Пример № 1. Требуется заблокировать объект и, если это удалось, модифицировать данные. В противном случае – проинформировать пользователя об отказе в выполнении операции с помощью сообщения вида:

      «Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено. Ошибка блокировки объекта. Объект уже заблокирован: компьютер: <имя компьютера>, пользователь: <имя пользователя>, сеанс: <номер сеанса>, начат: <дата и время>, приложение: <тип клиентского приложения>».

      \n

      ФайлОбъект = ДанныеФайла.Ссылка.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями; в случае блокировки -
      // вывести пользователю сообщение об исключении.
      ФайлОбъект.Заблокировать(); 
      // Затем изменить и записать объект
      ФайлОбъект.Редактирует = Справочники.Пользователи.ПустаяСсылка();
      ФайлОбъект.Записать();

      \n

      Аналогичным образом, можно воспользоваться методом глобального контекста ЗаблокироватьДанныеДляРедактирования:

      \n

      ФайлОбъект = ДанныеФайла.Ссылка.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями; в случае блокировки -
      // вывести пользователю сообщение об исключении.
      ЗаблокироватьДанныеДляРедактирования(ДанныеФайла.Ссылка); 
      // Затем изменить и записать объект
      ФайлОбъект.Редактирует = Справочники.Пользователи.ПустаяСсылка();
      ФайлОбъект.Записать();

      \n

      Пример № 2. Требуется пропустить обработку объекта, если он заблокирован для редактирования. При очередном вызове процедуры (например, из фонового или регламентного задания) будет предпринята повторная попытка изменения объекта.

      \n

      Объект = ТекущаяВерсия.ПолучитьОбъект();
      // Выполнить блокировку объекта от изменения другими режимами
      // или пользователями
      УстановитьПолноеНаименование = Истина;
      Попытка
        ФайлОбъект.Заблокировать();
      Исключение
        // в случае блокировки - не выполнять изменение объекта
        УстановитьПолноеНаименование = Ложь;
        // записать предупреждение в журнал регистрации
        ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Фоновое обновление имен файлов'\", Метаданные.ОсновнойЯзык.КодЯзыка),
          УровеньЖурналаРегистрации.Предупреждение,, ФайлОбъект, ОписаниеОшибки());
      КонецПопытки;

      \n

      // Пропустить обработку объекта, если он заблокирован.
      Если УстановитьПолноеНаименование Тогда
        Объект.ПолноеНаименование = ПолноеНаименование;
        Объект.Записать();
      КонецЕсли; 

      \n

      1.3. При редактировании данных в формах, платформа 1С:Предприятие автоматически устанавливает блокировку объекта, указанного в качестве основного реквизита формы.

      \n

      2. Не следует проверять блокировку объектов для редактирования в следующих случаях:

      \n
        \n
      • при выполнении отдельных операций, имеющих по логике работы больший приоритет по сравнению с интерактивными действиями пользователя. Например, загрузка данных при обмене; \n
      • при действиях, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы.
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1329", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Недопустимое одновременное использование ссылочных и нессылочных типов в составном типе.", +"Description": "

      Ограничения на использование реквизитов составного типа

      #std728

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      1.1. Реквизиты составного типа, используемые в условиях соединений, отборах, а также для упорядочивания, должны содержать только ссылочные типы (СправочникСсылка.[…], ДокументСсылка.[…] и пр.). В состав их типов не рекомендуется включать никаких других нессылочных типов, например: Строка, Число, Дата, УникальныйИдентификатор, Булево, а также ХранилищеЗначения.

      \n

      В противном случае производительность запросов заметно снизится. Это обусловлено особенностями физического хранения реквизитов составных типов в колонках таблиц СУБД. См. Особенности хранения составных типов данных (статья на ИТС).

      \n

      1.2. В отдельных случаях, для выполнения этой рекомендации можно применить следующий подход.

      \n

      Например, в документе определен реквизит Адрес составного типа, который включает ссылку на справочник Контакты и «строку» для возможности ввода в реквизит произвольных строковых значений. Вместо этого, следует предусмотреть отдельный справочник ПроизвольныеАдреса и указать его в реквизите Адрес вместо строки. При этом добавление новых элементов в справочник ПроизвольныеАдреса следует обеспечить автоматически, «незаметно» от пользователя, в момент записи документа. А удаление ненужных элементов справочника ПроизвольныеАдреса можно организовать посредством регламентного задания.

      \n

      2.1. Для типизированных объектов метаданных, хранящихся в информационной базе, не следует использовать составные типы ЛюбаяСсылка, СправочникСсылка, ДокументСсылка и аналогичные. Состав типов того или иного типизированного объекта должен определяться явным образом.

      \n

      Исключение составляют универсальные механизмы (алгоритмы), рассчитанные на работу с произвольными ссылочными объектами.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      2.2. В случае если составной тип массово используется в объектах какой-либо подсистемы или во всей конфигурации, то рекомендуется использовать определяемые типы.

      \n

      См. также:

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1330", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Недопустимое использование универсального составного типа (ЛюбаяСсылка, СправочникСсылка и т.п.).", +"Description": "

      Ограничения на использование реквизитов составного типа

      #std728

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      1.1. Реквизиты составного типа, используемые в условиях соединений, отборах, а также для упорядочивания, должны содержать только ссылочные типы (СправочникСсылка.[…], ДокументСсылка.[…] и пр.). В состав их типов не рекомендуется включать никаких других нессылочных типов, например: Строка, Число, Дата, УникальныйИдентификатор, Булево, а также ХранилищеЗначения.

      \n

      В противном случае производительность запросов заметно снизится. Это обусловлено особенностями физического хранения реквизитов составных типов в колонках таблиц СУБД. См. Особенности хранения составных типов данных (статья на ИТС).

      \n

      1.2. В отдельных случаях, для выполнения этой рекомендации можно применить следующий подход.

      \n

      Например, в документе определен реквизит Адрес составного типа, который включает ссылку на справочник Контакты и «строку» для возможности ввода в реквизит произвольных строковых значений. Вместо этого, следует предусмотреть отдельный справочник ПроизвольныеАдреса и указать его в реквизите Адрес вместо строки. При этом добавление новых элементов в справочник ПроизвольныеАдреса следует обеспечить автоматически, «незаметно» от пользователя, в момент записи документа. А удаление ненужных элементов справочника ПроизвольныеАдреса можно организовать посредством регламентного задания.

      \n

      2.1. Для типизированных объектов метаданных, хранящихся в информационной базе, не следует использовать составные типы ЛюбаяСсылка, СправочникСсылка, ДокументСсылка и аналогичные. Состав типов того или иного типизированного объекта должен определяться явным образом.

      \n

      Исключение составляют универсальные механизмы (алгоритмы), рассчитанные на работу с произвольными ссылочными объектами.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      2.2. В случае если составной тип массово используется в объектах какой-либо подсистемы или во всей конфигурации, то рекомендуется использовать определяемые типы.

      \n

      См. также:

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1331", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Задано конкретное значение цвета для элемента управления формы.", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1332", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Задано конкретное значение шрифта (либо изменен параметр шрифта из стиля) для элемента управления формы.", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1333", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Для элемента стиля задано конкретное значение шрифта, цвета или рамки.", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1334", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Устаревшая процедура (функция) ссылается на несуществующую процедуру (функцию).", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1335", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Устаревшая процедура (функция) ссылается на другую устаревшую процедуру (функцию).", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "1336", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Устаревшая процедура (функция) ссылается на процедуру (функцию), расположенную вне области \"ПрограммныйИнтерфейс\".", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1338", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неиспользуемый (с префиксом \"Удалить\") объект метаданных содержит подчиненные объекты, не относящиеся к переносу данных.", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1339", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Избыточная проверка параметра \"АвтоТест\".", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 5 +}, +{ +"Code": "134", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Количество параметров более 7.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "1340", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Процедура (функция), не являющаяся обработчиком события, расположена в стандартной области обработчиков событий.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1341", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Процедура (функция), являющаяся обработчиком события, расположена вне стандартной области обработчиков событий ", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1343", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Дублируется картинка.", +"Description": "

      Использование дублирующего кода

      #std440

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Дублированием кода называется способ разработки конфигурации, при котором при создании нового функционала копируются без изменений уже существующие фрагменты кода или целиком процедуры и функции и при этом копируемый функционал по логике приложения должен быть одинаковым.

      \n

      Дублирование кода создает проблемы для сопровождения разрабатываемой конфигурации:

      \n
        \n
      • в копию попадают все ошибки из дублируемого кода;  \n
      • при исправлении ошибок существует вероятность пропустить некоторые вхождения;  \n
      • затраты на исправление ошибок увеличиваются;  \n
      • усложняется понимание структуры программы.
      \n

      Дублирование часто возникает из-за невозможности доступа к написанному прежде коду (например, если написанный прежде код размещен в модуле той или иной формы, а его использование востребовано при разработке другой формы).

      Следует осторожно относиться к дублированию кода и по возможности стараться его избегать. Основной способ избежать дублирования кода - переработать существующий код. Это позволит вывести процедуры и функции, алгоритмы которых могут быть использованы повторно, из модулей объектов и модулей форм в общие модули.

      \n

      2. Следует помнить, что дублирование кода оправданно и должно выполняться, если развитие функционала в будущем может привести к значительному расхождению двух вариантов кода.

      \n

      Пример предотвращения дублирования кода при разработке клиент-серверных функций

      \n

      В функции СообщитьПользователю общего модуля ОбщегоНазначенияКлиентСервер возникла необходимость особым образом обработать входные параметры при выполнении на сервере.

      \n

      Неправильно использовать для этого инструкции препроцессора (#Если НЕ ТонкийКлиент И НЕ ВебКлиент):

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       Сообщение = Новый СообщениеПользователю;
       Сообщение.Текст = ТекстСообщенияПользователю;
       Сообщение.Поле = Поле;
       
       ЭтоОбъект = Ложь;
       
      #Если НЕ ТонкийКлиент И НЕ ВебКлиент Тогда
       Если КлючДанных <> Неопределено
          И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
        ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
        ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, \"Object.\") > 0;
       КонецЕсли;
      #КонецЕсли
       
       Если ЭтоОбъект Тогда
        Сообщение.УстановитьДанные(КлючДанных);
       Иначе
        Сообщение.КлючДанных = КлючДанных;
       КонецЕсли;
       
       Сообщение.Сообщить();
       Отказ = Истина;
       
      КонецПроцедуры

      \n

      Правильно разделить процедуру на две одноименные в серверном и клиентском модуле с различной реализацией, и для того чтобы избежать дублирования кода, общую реализацию оставить в клиент-серверном общем модуле:

      \n

      1) серверная функция:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       ЭтоОбъект = Ложь;
       Если КлючДанных <> Неопределено
        И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
        
        ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
        ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, \"Object.\") > 0;
       КонецЕсли;
       
       ОбщегоНазначенияСлужебныйКлиентСервер.СообщитьПользователю(ТекстСообщенияПользователю, КлючДанных, Поле, Отказ, ЭтоОбъект);
       
      КонецПроцедуры

      \n

      2) клиентская функция:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       ОбщегоНазначенияСлужебныйКлиентСервер.СообщитьПользователю(ТекстСообщенияПользователю, КлючДанных, Поле, Отказ);
       
      КонецПроцедуры

      \n

      3) общая служебная клиент-серверная реализация в модуле ОбщегоНазначенияСлужебныйКлиентСервер:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных, Знач Поле, Отказ = Ложь, ЭтоОбъект = Ложь) Экспорт
       
       Сообщение = Новый СообщениеПользователю;
       Сообщение.Текст = ТекстСообщенияПользователю;
       Сообщение.Поле = Поле;
       
       Если ЭтоОбъект Тогда
        Сообщение.УстановитьДанные(КлючДанных);
       Иначе
        Сообщение.КлючДанных = КлючДанных;
       КонецЕсли;
       
       Сообщение.Сообщить();
       Отказ = Истина;
       
      КонецПроцедуры

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "1344", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Дублируется наименование картинки.", +"Description": "

      Использование дублирующего кода

      #std440

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Дублированием кода называется способ разработки конфигурации, при котором при создании нового функционала копируются без изменений уже существующие фрагменты кода или целиком процедуры и функции и при этом копируемый функционал по логике приложения должен быть одинаковым.

      \n

      Дублирование кода создает проблемы для сопровождения разрабатываемой конфигурации:

      \n
        \n
      • в копию попадают все ошибки из дублируемого кода;  \n
      • при исправлении ошибок существует вероятность пропустить некоторые вхождения;  \n
      • затраты на исправление ошибок увеличиваются;  \n
      • усложняется понимание структуры программы.
      \n

      Дублирование часто возникает из-за невозможности доступа к написанному прежде коду (например, если написанный прежде код размещен в модуле той или иной формы, а его использование востребовано при разработке другой формы).

      Следует осторожно относиться к дублированию кода и по возможности стараться его избегать. Основной способ избежать дублирования кода - переработать существующий код. Это позволит вывести процедуры и функции, алгоритмы которых могут быть использованы повторно, из модулей объектов и модулей форм в общие модули.

      \n

      2. Следует помнить, что дублирование кода оправданно и должно выполняться, если развитие функционала в будущем может привести к значительному расхождению двух вариантов кода.

      \n

      Пример предотвращения дублирования кода при разработке клиент-серверных функций

      \n

      В функции СообщитьПользователю общего модуля ОбщегоНазначенияКлиентСервер возникла необходимость особым образом обработать входные параметры при выполнении на сервере.

      \n

      Неправильно использовать для этого инструкции препроцессора (#Если НЕ ТонкийКлиент И НЕ ВебКлиент):

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       Сообщение = Новый СообщениеПользователю;
       Сообщение.Текст = ТекстСообщенияПользователю;
       Сообщение.Поле = Поле;
       
       ЭтоОбъект = Ложь;
       
      #Если НЕ ТонкийКлиент И НЕ ВебКлиент Тогда
       Если КлючДанных <> Неопределено
          И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
        ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
        ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, \"Object.\") > 0;
       КонецЕсли;
      #КонецЕсли
       
       Если ЭтоОбъект Тогда
        Сообщение.УстановитьДанные(КлючДанных);
       Иначе
        Сообщение.КлючДанных = КлючДанных;
       КонецЕсли;
       
       Сообщение.Сообщить();
       Отказ = Истина;
       
      КонецПроцедуры

      \n

      Правильно разделить процедуру на две одноименные в серверном и клиентском модуле с различной реализацией, и для того чтобы избежать дублирования кода, общую реализацию оставить в клиент-серверном общем модуле:

      \n

      1) серверная функция:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       ЭтоОбъект = Ложь;
       Если КлючДанных <> Неопределено
        И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
        
        ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
        ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, \"Object.\") > 0;
       КонецЕсли;
       
       ОбщегоНазначенияСлужебныйКлиентСервер.СообщитьПользователю(ТекстСообщенияПользователю, КлючДанных, Поле, Отказ, ЭтоОбъект);
       
      КонецПроцедуры

      \n

      2) клиентская функция:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = \"\", Отказ = Ложь) Экспорт
       
       ОбщегоНазначенияСлужебныйКлиентСервер.СообщитьПользователю(ТекстСообщенияПользователю, КлючДанных, Поле, Отказ);
       
      КонецПроцедуры

      \n

      3) общая служебная клиент-серверная реализация в модуле ОбщегоНазначенияСлужебныйКлиентСервер:

      \n

      Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных, Знач Поле, Отказ = Ложь, ЭтоОбъект = Ложь) Экспорт
       
       Сообщение = Новый СообщениеПользователю;
       Сообщение.Текст = ТекстСообщенияПользователю;
       Сообщение.Поле = Поле;
       
       Если ЭтоОбъект Тогда
        Сообщение.УстановитьДанные(КлючДанных);
       Иначе
        Сообщение.КлючДанных = КлючДанных;
       КонецЕсли;
       
       Сообщение.Сообщить();
       Отказ = Истина;
       
      КонецПроцедуры

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1345", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использование конструкции \"Новый Шрифт\"", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1346", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использование конструкции \"Новый Цвет\"", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1347", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использование конструкции \"Новый Рамка\"", +"Description": "

      Элементы стиля

      #std667

      Область применения: управляемое приложение.

      \n

      Для каждого элемента управления оформление по умолчанию задается платформой. Умолчаний следует придерживаться в большинстве случаев — это позволяет обеспечить единообразное оформление всех форм.

      \n

      В некоторых ситуациях возникает потребность визуально выделить конкретный элемент управления среди других, изменив его оформление по умолчанию.

      \n

      Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления. Это требуется для того, чтобы аналогичные элементы управления выглядели одинаково во всех формах, где они встречаются.

      \n

      Виды элементов стиля:
      • Цвет (задается значение RGB)
      • Шрифт (задаются вид, размер и начертание)
      • Рамка (задаются тип и ширина границ)

      \n

      1. Элементы стиля нужно использовать всегда, когда требуется изменить оформление (Цвет, Шрифт, Рамку), установленные по умолчанию.

      \n

      Например, информационные надписи среди других надписей можно выделить с помощью цвета. Цвет таких надписей следует задавать в виде элемента стиля \"ИнформационнаяНадпись\", а не в виде значения RGB или выбора цвета web/windows:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

      \n

      2. Не следует использовать элементы стиля для того, чтобы подменить оформление, которое используется по умолчанию в платформе.

      \n

      Например, для гиперссылок нужно использовать цвет, предусмотренный в платформе, а не создавать для него свой элемент стиля с точно таким же цветом:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      \n

      \n

       

      \n

      3. Каждый элемент стиля следует создавать для применения в конкретной ситуации. Если такой же цвет или шрифт нужно использовать в другой ситуации, то для нее нужно создать отдельный элемент стиля.

      \n

      Например, цвет элемента стиля \"ФонУправляющегоПоля\" следует применять только для фона полей, которые влияют на видимость других полей в форме. Если такой же цвет фона предполагается использовать для поля с другим назначением, то для него нужно создать отдельный элемент стиля.

      \n

      4. Название для элемента стиля следует подбирать таким образом, чтобы в нем отразить назначение элемента стиля.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n\n\n\n
      Название элемента стиляНазначение
      ФонУправляющегоПоляФон поля, которое управляет видимостью других полей
      ТекстНевыбраннойКартинкиТекст, который будет отражается на картинке, пока она не выбрана

      \n

      5. Для нескольких элементов стиля, имеющих одинаковое название, но разный вид, рекомендуется включать вид (слова \"Цвет\", \"Шрифт\", \"Рамка\") в название:

      \n

      Например: \"ТекстНевыбраннойКартинкиЦвет\" и \"ТекстНевыбраннойКартинкиШрифт\".

      \n

      При этом вид элемента стиля (Цвет, Шрифт, Рамка) следует указывать после его названия. Это требуется для того, чтобы можно было по первым буквам найти нужный элемент стиля в списке.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ПросроченныеДанныеЦвет
      ПросроченныеДанныеШрифт

      \n

      ЦветПросроченныхДанных
      ШрифтПросроченныхДанных

      \n

      В названии элемента стиля следует указывать только тот вид (Цвет, Шрифт, Рамка), который используется фактически.

      \n

      Например, для элемента стиля вида \"Цвет\" не следует включать в название слово \"Шрифт\":

      \n

      \n\n\n\n\n\n\n\n
      \n

      Хорошо

      \n

      Плохо

      \n

      ВажнаяНадпись

      \n

      \n

      ШрифтВажнойНадписи

      \n

      \n

       

      \n

      Элементы стиля с видом \"Цвет\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
       Элемент стиля\n

       Значение  (RGB)

       В каком стандарте используется
       ПросроченныеДанные 178,34,34 \n\n\n\n
      \n

       Акцентирование внимания на просроченных или критичных состояниях 

      \n

       Итоги в документах

       ПояснениеОтсутствующейГиперссылки128,128,128 \n\n\n\n
       Гиперссылка на счет-фактуру
       ТекстЗапрещеннойЯчейки192,192,192 \n\n\n\n
       Пояснение невозможности заполнения ячеек в табличных частях
       ИтоговыеПоказателиДокументов22,39,121 \n\n\n\n
       Итоги в документах
       ИтогиЖурналаЦвет100,100,100 \n\n\n\n
       Итоги в журналах документов
       ФонУправляющего поля255,232,179 \n\n\n\n
       Поле, влияющее на состав остальных полей в форме
      \n

       ТекстНевыбраннойКартинкиЦвет

      \n

      220,220,220

      \n\n\n\n
      Невыбранная картинка
      \n

       НегативноеСобытие

      \n

      178,34,34

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       ПозитивноеСобытие

      \n

      0,128,0

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       НеактуальнаяИнформация

      \n

      255,200,200

      \n\n\n\n
      Отчеты вида \"таблица\", \"список\"
      \n

       Диаграмма

      \n

      70,130,180

      \n\n\n\n
      Отчеты вида \"диаграмма\"
       Прогноз\n

      199,21,133

      \n\n\n\n
      Отчеты вида \"диаграмма\"
      ПоясняющийТекст\n

      128,122,89

      \n\n\n\n
      Рабочее место

      \n

       

      \n

      Элементы стиля с видом \"Шрифт\"

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Элемент стиляЗначение (шрифт, размер, начертание)В каком стандарте используется
      ОсновнойЭлементСпискаШрифт диалогов и меню, начертание: ПолужирныйЗначения по умолчанию
      ОсновноеИтоговоеЗначениеШрифт диалогов и меню, начертание: ПолужирныйИтоги в документах
      ИтогиЖурналаШрифтШрифт диалогов и меню, начертание: ПолужирныйИтоги в журналах документов
      ТекстНевыбраннойКартинкиШрифтШрифт диалогов и меню, размер: 12Невыбранная картинка

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1348", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использован метод глобального контекста вместо процедуры общего модуля \"ФайловаяСистемаКлиент\"", +"Description": "

      Установка внешних компонент и расширений платформы

      #std700

      Область применения: управляемое приложение.

      \n

      1.1. Установка внешних компонент и расширений платформы должна быть интерактивной. Пользователь должен самостоятельно принять решение об установке. В диалоге установки должно быть указано, для чего нужна компонента (расширение) и что не будет работать, если ее не устанавливать.

      \n

      Например, неправильно использовать конструкции вида

      \n

      Если Не ПодключитьВнешнююКомпоненту(…) Тогда
        УстановитьВнешнююКомпоненту(…)

      \n

      Правильно задавать пользователю вопрос в явном виде:

      \n
      \n

      Для продолжения работы требуется установить внешнюю компоненту, которая позволит работать с отчетностью. Для установки компоненты нажмите \"Установить\". После завершения установки нажмите \"Продолжить\".

      \n

      1.2. Рекомендуется выводить предложение об установки компоненты (расширения) перед выполнениям прикладного действия.
      Например:

      \n
        \n
      • Пользователь воспользовался командой «Отправить отчет» \n
      • Для этого конфигурации необходимо, чтобы была установлена какая-либо внешняя компонента. \n
      • Конфигурация проверяет, установлена ли компонента. \n
      • Если компонента не установлена, отображает пользователю информацию о том, что для отправки отчета нужно установить компоненту и кнопку, вызывающую установку компоненты. \n
      • Пользователь нажимает на кнопку, выполняется установка. \n
      • После установки пользователь нажимает на кнопку «Продолжить отправку отчета» \n
      • Программа продолжает отправлять отчет.
      \n

      Такой сценарий позволит обеспечить, чтобы компоненты (расширения) устанавливались без проблем на всех поддерживаемых браузерах, в том числе, в браузере FireFox.

      \n

      Другой пример. Предложение об установке расширения работы с файлами при загрузке файла из файловой системы:

      \n

      \n

      1.3. При использовании в конфигурации Библиотеки стандартных подсистем для вывода предложения об установке расширения работы с файлами следует использовать следующие процедуры общего модуля ФайловаяСистемаКлиент в следующих сценариях:

      \n
        \n
      • ВыбратьКаталог вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы ВыборКаталога; \n
      • ЗагрузитьФайл вместо методов глобального контекста ПоместитьФайл, НачатьПомещениеФайла, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Открытие; \n
      • ЗагрузитьФайлы вместо методов глобального контекста ПоместитьФайлы, НачатьПомещениеФайлов, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Открытие; \n
      • ОткрытьФайл вместо метода глобального контекста ЗапуститьПриложение для открытия файла, ассоциированного с некоторым приложением; \n
      • СохранитьФайл вместо метода глобального контекста ПолучитьФайл или метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Сохранение; \n
      • СохранитьФайлы вместо методов глобального контекста ПолучитьФайлы, НачатьПолучениеФайлов, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Сохранение. \n
      • В остальных случаях, для вывода предложения об установке расширения работы с файлами следует использовать процедуру ПодключитьРасширениеДляРаботыСФайлами.

        \n
      \n


      2. В прикладном решении должны быть предоставлены инструменты для установки пользователем внешних компонент и расширений в любой момент работы. Таким образом, их можно установить не только в ходе решения какой-то задачи, но и в виде отдельного действия (из некоторого административного режима).

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем для установки расширения для работы с файлами предназначена общая команда УстановитьРасширениеРаботыСФайлами, которую рекомендуется размещать в форме персональных настроек пользователя (см. общую форму _ДемоМоиНастройки в демонстрационной конфигурации). В этой же форме рекомендуется размещать команды по установке внешних компонент, которые могут потребоваться пользователю при его работе.

      \n

      См. также

      \n\n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1349", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра обработчика оповещения указана несуществующая процедура.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1350", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра обработчика оповещения указана функция.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1351", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра обработчика оповещения указана неэкспортная процедура.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1352", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра обработчика оповещения указана процедура без параметров.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1353", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Английский идентификатор в коде модуля на русском языке.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1354", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Локализуемая строка состоит из нелокализуемых символов.", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n\n\n\n

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1355", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Конкатенация локализуемых строк.", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1356", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра конструктора \"Новый ФорматированнаяСтрока\" использована составная форматированная строка.", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1357", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра метода \"ЧислоПрописью\" используется форматированная строка с параметром \"Л=\"(\"L=\") .", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1358", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра метода \"ПредставлениеПериода\" используется форматированная строка с параметром \"Л=\"(\"L=\") .", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1359", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве параметра метода \"СтрокаСЧислом\" используется форматированная строка с параметром \"Л=\"(\"L=\") .", +"Description": "

      Интерфейсные тексты в коде: требования по локализации

      #std761

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

      \n

      Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

      \n

      Например, неправильно:

      ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
      \n

      Также следует обращать внимание на корректное использование функции НСтр.

      \n

      Например, неправильно:

      ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
      \n

      2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

      \n

      Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

      \n

      Неправильно:

      СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
      СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
      \n

      Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

      \n

      Неправильно:

      НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
      \n

      Правильно:

      НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
      НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
      \n

      В то же время допустимым является:

      \n
        \n
      1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
      2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
      \n

      В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

      \n

      Правильно:

      СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

      \n

      Неправильно:

      Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
      \n

      Правильно:

      \n

      ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

      \n

      4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

      \n

      Неправильно:

      ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
      \n

      Правильно:

      ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
      \n

      5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

      Неправильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      Правильно:

      СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

      6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

      \n

      Неправильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
      \n

      Правильно:

      ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
      \n

      В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

      \n

      7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
      • следует по возможности использовать системное перечисление КодВозвратаДиалога;
      • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

      \n

      Например, неправильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
      \n

      Правильно:

      Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1360", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Некорректно описан тип элементов массива.", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "1361", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В макете с типом \"ВнешняяКомпонента\" размешен файл с другим типом.", +"Description": "

      Макеты: требования по локализации и поддержке разных языков интерфейса

      #std766

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Как правило, перевод табличных, текстовых и HTML-макетов на другие языки не требует каких-либо подготовительных действий при разработке конфигурации. Особым случаем являются двоичные макеты, подлежащие переводу, а также HTML-макеты, содержащие изображения, которые должны быть отдельно подготовлены на разных языках. Например, это двоичные макеты печатных форм в форматах офисных документов, HTML-макеты с инструкциями, включающие скриншоты интерфейса программы или изображения, содержащие текстовую информацию.

      \n

      Такой макет необходимо пометить специальным образом, пометка будет означать, что при переводе будет необходимо создавать копию, а не переводить содержимое макета. Для этого в имени макета следует указывать постфикс в виде подчеркивания и кода языка так, как он задан в метаданных, в языке Русский в свойстве Код языка: \"_ru\".
      Например, неправильно:

      \n

      макет ПФ_ODT_СчетНаОплату (макет печатной формы счета на оплату в формате OpenOffice Writer)

      \n

      правильно указывать в имени постфикс основного языка:

      \n

      макет ПФ_ODT_СчетНаОплату_ru

      \n

      При добавлении языков интерфейса следует добавлять макеты с соответствующими постфиксами. В коде, в зависимости от языка, использовать макет с соответствующим постфиксом. Например, неправильно:

      ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\");\n
      \n

      правильно:

      \n

      ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\" +  \"_\" + ТекущийЯзык());

      \n

      Кроме того, для исключения ошибок при частичном переводе конфигурации, рекомендуется выполнять получение макета в три этапа:

      \n
        \n
      • Сначала по ИмяМакета + \"_\" + ТекущийЯзык(); \n
      • Если не найден, то по ИмяМакета + \"_\" + Метаданные.ОсновнойЯзык.КодЯзыка; \n
      • Если не найден, то по переданному имени ИмяМакета. \n
      • И наконец установить свойство КодЯзыка (у табличного документа) или КодЯзыкаМакета (у текстового документа и HTML-макета), как указано далее в п.2.
      \n

      2. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может возникнуть задача в одном сеансе пользователя формировать печатные формы на разных языках, а не только на текущем языке интерфейса. Например, в сеансе англоязычного пользователя сформировать счет на оплату на русском языке.

      \n

      Для получения данных из табличного, текстового или HTML-макета на заданном языке, отличном от языка интерфейса текущего пользователя, необходимо использовать свойство КодЯзыка (доступно у табличного документа) и КодЯзыкаМакета (у текстового документа и HTML-макета).

      \n

      Правильно:

      Макет = ПолучитьОбщийМакет(\"ПечатнаяФорма\");\nМакет.КодЯзыкаМакета = \"ru\";\nHTMLДокумент = Макет.ПолучитьДокументHTML();\n
      \n

      3. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может также возникнуть задача формировать печатные формы строго на одном языке, не зависимо от текущего языка интерфейса. Примером таких макетов могут служить регламентированные формы отчетности для государственных учреждений. Например, пользователи с любым языком интерфейса должны формировать русскоязычную счет-фактуру – налоговый документ строго установленного образца в соответствии с Налоговым кодексом Российской Федерации (не существует российских счет-фактур на других языках, кроме русского).

      \n

      Для табличных и HTML-макетов, которые должны выводится пользователю и на печать строго на одном языке, следует

      \n
        \n
      • указывать в наименовании постфикс кода языка, аналогично п.1 \n
      • и устанавливать код языка макета аналогично п.2 при программном получении макета в коде.
      \n

      Такие макеты не должны переводиться на другие языки интерфейса. При программном формировании текстов для заполнения макета следует явно указывать второй параметр в функции НСтр() для того, чтобы строки были сформированы на том же языке, что и макет.

      \n

      Например, не правильно:

      Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура\");\n...\nОбласть.Текст = НСтр(\"ru='Заголовок печати';\");\n
      \n

      Правильно:

      \n

      Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура_ru\");
      Макет.КодЯзыка = Метаданные().Языки.Русский.КодЯзыка;
      ...
      Область.Текст = НСтр(\"ru='Заголовок печати';\", Метаданные().Языки.Русский.КодЯзыка);

      \n

      При использовании Библиотеки стандартных подсистем (БСП) и подсистемы Печать получение макета через функцию УправлениеПечатью.МакетПечатнойФормы(\"ПФ_MXL_СчетФактура\") позволяет получить форму ПФ_MXL_СчетФактура_ru и устанавливает у макета свойство КодЯзыка.

      \n

      4. Если в текстах макетов используются именованные параметры подстановки, необходимо соблюдать для них требования по локализации интерфейсных текстов в коде.

      \n

      5. Кодировку в макетах использовать UTF-8.

      \n

      6. Также, по возможности, следует группировать однотипные макеты (использовать один макет вместо нескольких). Например, в следующем примере в конфигурации имеется несколько однотипных макетов с сообщениями, но их содержимое записывается в один справочник, поэтому правильно хранить все подобные сообщения в одном макете.

      \n

      Неправильно:

       
      Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(\"Сообщение\");\n
      \n

      Правильно:

      \n

       

      Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(\"Сообщения_%1\", ОбщегоНазначения.КодОсновногоЯзыка()));
      \n

      7. Внешние компоненты следует размешать в макетах с типом макета внешняя компонента. При разработке внешней компоненты требуется обрабатывать метод SetLocale для локализации внешней компоненты в соответствии с полученным кодом локализации (см. Технология создания внешних компонент). Если полученный код локализации отличается от предусмотренного во внешней компоненте, то компонента должна настроить свое окружение на использование английского языка.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1363", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В обработчике обновления информационной базы при записи объекта не используется метод \"Библиотеки стандартных подсистем\".\n", +"Description": "

      Обработчики обновления информационной базы

      #std690

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций на базе Библиотеки стандартных подсистем.
      Содержит уточнения к требованиям других стандартов.
      См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС.

      \n

      1. Основные сведения о библиотеке (основной конфигурации)
      2. Расположение обработчиков обновления
      3. Реализация обработчиков обновления
      4. Переход на новые версии библиотек

      \n

      1. Основные сведения о библиотеке (основной конфигурации)

      \n

      1.1. При разработке конфигураций на базе библиотек, каждая библиотека должна сообщить о себе ряд сведений, необходимых для корректного обновления информационной базы на новую версию конфигурации:

      \n
        \n
      • Имя \n
      • Версию \n
      • Список обработчиков обновления \n
      • Зависимости от других библиотек.
      \n

      Эти сведения размещаются в специальном общем модуле библиотеки, имя которого должно начинаться с ОбновлениеИнформационнойБазы…
      Пример:
      В конфигурации УТ 11 модуль обработчиков обновления называется ОбновлениеИнформационнойБазыУТ

      \n

      Имена модулей всех используемых в конфигурации библиотек следует явно перечислить в общем модуле ПодсистемыКонфигурацииПереопределяемый в виде:

      \n

      Процедура ПриДобавленииПодсистем(МодулиПодсистем) Экспорт

      \n

       МодулиПодсистем.Добавить(\"ОбновлениеИнформационнойБазыУТ\");

      \n

      КонецПроцедуры

      \n

      Кроме того, аналогичный модуль также должен быть определен и для основной конфигурации.

      \n

      При создании общего модуля ОбновлениеИнформационнойБазы… следует использовать шаблон:

      \n

      ////////////////////////////////////////////////////////////////////////////////
      // Обновление информационной базы <библиотеки или конфигурации>.
      //
      /////////////////////////////////////////////////////////////////////////////

      \n

      #Область ПрограммныйИнтерфейс

      \n

      ////////////////////////////////////////////////////////////////////////////////
      // Получение сведений о библиотеке (или конфигурации).

      \n

      // Заполняет основные сведения о библиотеке или основной конфигурации.
      // Библиотека, имя которой имя совпадает с именем конфигурации в метаданных, определяется как основная конфигурация.
      //
      // Параметры:
      //  Описание - Структура - сведения о библиотеке:
      //
      //   Имя                 - Строка - имя библиотеки, например, \"СтандартныеПодсистемы\".
      //   Версия              - Строка - версия в формате из 4-х цифр, например, \"2.1.3.1\".
      //
      //   ТребуемыеПодсистемы - Массив - имена других библиотек (Строка), от которых зависит данная библиотека.
      //                                  Обработчики обновления таких библотек должны быть вызваны ранее
      //                                  обработчиков обновления данной библиотеки.
      //                                  При циклических зависимостях или, напротив, отсутствии каких-либо зависимостей,
      //                                  порядок вызова обработчиков обновления определяется порядком добавления модулей
      //                                  в процедуре ПриДобавленииПодсистем общего модуля ПодсистемыКонфигурацииПереопределяемый.
      //   РежимВыполненияОтложенныхОбработчиков - Строка - \"Последовательно\" - отложенные обработчики обновления выполняются
      //                                    последовательно в интервале от номера версии информационной базы до номера
      //                                    версии конфигурации включительно или \"Параллельно\" - отложенный обработчик после
      //                                    обработки первой порции данных передает управление следующему обработчику, а после
      //                                    выполнения последнего обработчика цикл повторяется заново.
      //
      Процедура ПриДобавленииПодсистемы(Описание) Экспорт
       
       Описание.Имя    = \"<Имя библиотеки>\";
       Описание.Версия = \"XX.XX.XX.XX\";
       Описание.ТребуемыеПодсистемы.Добавить(\"СтандартныеПодсистемы\");
       Описание.РежимВыполненияОтложенныхОбработчиков = \"Последовательно\";
       
      КонецПроцедуры

      \n

      ////////////////////////////////////////////////////////////////////////////////
      // Обработчики обновления информационной базы.

      \n

      // Добавляет в список процедуры-обработчики обновления данных ИБ
      // для всех поддерживаемых версий библиотеки или конфигурации.
      // Вызывается перед началом обновления данных ИБ для построения плана обновления.
      //
      // Параметры:
      //  Обработчики - ТаблицаЗначений - описание полей
      //                                  см. в процедуре ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления
      //
      // Пример добавления процедуры-обработчика в список:
      //  Обработчик = Обработчики.Добавить();
      //  Обработчик.Версия              = \"1.0.0.0\";
      //  Обработчик.Процедура           = \"ОбновлениеИБ.ПерейтиНаВерсию_1_0_0_0\";
      //  Обработчик.РежимВыполнения     = \"Монопольно\";
      //
      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт

       // Обработчики, выполняемые при каждом обновлении ИБ
       
       // Обработчики, выполняемые при переходе на определенную версию

      \n

       // Обработчики, выполняемые при заполнении пустой ИБ

      КонецПроцедуры

      \n

      // Вызывается перед процедурами-обработчиками обновления данных ИБ.
      //
      Процедура ПередОбновлениемИнформационнойБазы() Экспорт
       
      КонецПроцедуры

      \n

      // Вызывается после завершения обновления данных ИБ.
      //
      // Параметры:
      //   ПредыдущаяВерсия       - Строка - версия до обновления. \"0.0.0.0\" для \"пустой\" ИБ.
      //   ТекущаяВерсия          - Строка - версия после обновления.
      //   ВыполненныеОбработчики - ДеревоЗначений - список выполненных процедур-обработчиков обновления,
      //                                             сгруппированных по номеру версии.
      //   ВыводитьОписаниеОбновлений - Булево - (возвращаемое значение) если установить Истина,
      //                                то будет вывена форма с описанием обновлений. По умолчанию, Истина.
      //   МонопольныйРежим           - Булево - Истина, если обновление выполнялось в монопольном режиме.
      //
      Процедура ПослеОбновленияИнформационнойБазы(Знач ПредыдущаяВерсия, Знач ТекущаяВерсия,
        Знач ВыполненныеОбработчики, ВыводитьОписаниеОбновлений, МонопольныйРежим) Экспорт
       
      КонецПроцедуры

      \n

      // Вызывается при подготовке табличного документа с описанием изменений в программе.
      //
      // Параметры:
      //   Макет - ТабличныйДокумент - описание обновления всех библиотек и конфигурации.
      //           Макет можно дополнить или заменить.
      //           См. также общий макет ОписаниеИзмененийСистемы.
      //
      Процедура ПриПодготовкеМакетаОписанияОбновлений(Знач Макет) Экспорт
       
      КонецПроцедуры

      \n

      // Позволяет переопределить режим обновления данных информационной базы.
      // Для использования в редких (нештатных) случаях перехода, не предусмотренных в
      // стандартной процедуре определения режима обновления.
      //
      // Параметры:
      //   РежимОбновленияДанных - Строка - в обработчике можно присвоить одно из значений:
      //              \"НачальноеЗаполнение\"     - если это первый запуск пустой базы (области данных);
      //              \"ОбновлениеВерсии\"        - если выполняется первый запуск после обновление конфигурации базы данных;
      //              \"ПереходСДругойПрограммы\" - если выполняется первый запуск после обновление конфигурации базы данных,
      //                                          в которой изменилось имя основной конфигурации.
      //
      //   СтандартнаяОбработка  - Булево - если присвоить Ложь, то стандартная процедура
      //                                    определения режима обновления не выполняется,
      //                                    а используется значение РежимОбновленияДанных.
      //
      Процедура ПриОпределенииРежимаОбновленияДанных(РежимОбновленияДанных, СтандартнаяОбработка) Экспорт
       
      КонецПроцедуры

      \n

      // Добавляет в список процедуры-обработчики перехода с другой программы (с другим именем конфигурации).
      // Например, для перехода между разными, но родственными конфигурациями: базовая -> проф -> корп.
      // Вызывается перед началом обновления данных ИБ.
      //
      // Параметры:
      //  Обработчики - ТаблицаЗначений - с колонками:
      //    * ПредыдущееИмяКонфигурации - Строка - имя конфигурации, с которой выполняется переход;
      //                                           или \"*\", если нужно выполнять при переходе с любой конфигурации.
      //    * Процедура                 - Строка - полное имя процедуры-обработчика перехода с программы ПредыдущееИмяКонфигурации.
      //                                  Например, \"ОбновлениеИнформационнойБазыУПП.ЗаполнитьУчетнуюПолитику\"
      //                                  Обязательно должна быть экспортной.
      //
      // Пример добавления процедуры-обработчика в список:
      //  Обработчик = Обработчики.Добавить();
      //  Обработчик.ПредыдущееИмяКонфигурации  = \"УправлениеТорговлей\";
      //  Обработчик.Процедура                  = \"ОбновлениеИнформационнойБазыУПП.ЗаполнитьУчетнуюПолитику\";
      //
      Процедура ПриДобавленииОбработчиковПереходаСДругойПрограммы(Обработчики) Экспорт
       
      КонецПроцедуры

      \n

      // Вызывается после выполнения всех процедур-обработчиков перехода с другой программы (с другим именем конфигурации),
      // и до начала выполнения обновления данных ИБ.
      //
      // Параметры:
      //  ПредыдущееИмяКонфигурации    - Строка - имя конфигурации до перехода.
      //  ПредыдущаяВерсияКонфигурации - Строка - имя предыдущей конфигурации (до перехода).
      //  Параметры                    - Структура -
      //    * ВыполнитьОбновлениеСВерсии   - Булево - по умолчанию Истина. Если установить Ложь,
      //        то будут выполнена только обязательные обработчики обновления (с версией \"*\").
      //    * ВерсияКонфигурации           - Строка - номер версии после перехода.
      //        По умолчанию, равен значению версии конфигурации в свойствах метаданных.
      //        Для того чтобы выполнить, например, все обработчики обновления с версии ПредыдущаяВерсияКонфигурации,
      //        следует установить значение параметра в ПредыдущаяВерсияКонфигурации.
      //        Для того чтобы выполнить вообще все обработчики обновления, установить значение \"0.0.0.1\".
      //    * ОчиститьСведенияОПредыдущейКонфигурации - Булево - по умолчанию Истина.
      //        Для случаев когда предыдущая конфигурация совпадает по имени с подсистемой текущей конфигурации, следует указать Ложь.
      //
      Процедура ПриЗавершенииПереходаСДругойПрограммы(Знач ПредыдущееИмяКонфигурации,
       Знач ПредыдущаяВерсияКонфигурации, Параметры) Экспорт
       
      КонецПроцедуры

      \n

      #КонецОбласти

      \n

      #Область СлужебныеПроцедурыИФункции

      \n

      ////////////////////////////////////////////////////////////////////////////////
      // Заполнение пустой ИБ

      \n

      ////////////////////////////////////////////////////////////////////////////////
      // Обновление ИБ

      \n

      #КонецОбласти

      \n

      1.2. Обработчики обновления данных информационной базы предназначены для дополнительной обработки данных после завершения обновления конфигурации (реструктуризации) базы данных:

      \n
        \n
      • инициализация новых констант, новых реквизитов, реквизитов новых предопределенных элементов; \n
      • перенос данных из устаревших структур метаданных в новые; \n
      • генерация новых данных \n
      • и т.п.
      \n

      Для автогенерируемых строк, которые программно записываются в информационную базу, например при заполнении наименований предопределенных элементов справочников, ПВХ и т.п., следует руководствоваться стандартом Автогенерированные данные в информационной базе: требования по локализации.

      \n

      1.3. Обработчик обновления данных информационной базы состоит из двух частей:

      \n
        \n
      • \n
        описательной - сообщает, когда должен выполниться обработчик, и где он находится в конфигурации;
        \n
      • \n
        программной  - непосредственно код модификации данных ИБ, оформленный в виде процедуры-обработчика обновления.
      \n

      Добавление описаний новых обработчиков выполняется в процедуре ПриДобавленииОбработчиковОбновления с помощью вставки фрагмента кода по шаблону:

      \n

      Обработчик = Обработчики.Добавить();
      Обработчик.Версия = \"<номер версии>\";
      Обработчик.Процедура = \"<полное имя экспортной процедуры>\";
      Обработчик.НачальноеЗаполнение = {Истина|Ложь};
      Обработчик.РежимВыполнения = {\"Монопольно\"|\"Оперативно\"|\"Отложенно\"};

      \n

      Данный код добавляет новую строку в таблицу значений Обработчики, строка которой имеет следующие поля:

      \n

      Версия (Строка) – номер версии конфигурации, при обновлении на которую должна быть вызвана процедура обновления, указанная в параметре Процедура.

      \n
        \n
      • \n
        Номер версии конфигурации указывается в формате «Р.П.В.С» (Р – старший номер редакции; П – младший номер редакции; В – номер версии; С – номер сборки. Если следующую версию нельзя определить, то можно указать следующий номер сборки.
        \n
      • \n
        Если в качестве версии указан символ «*», то обработчик обновления должен выполняться каждый раз при обновлении информационной базы, независимо от номера версии конфигурации. Обработчики такого вида предназначены для обновления служебных, системных данных (например, обновление поставляемых профилей и групп доступа).
        \n
      • \n
        Если свойство Версия не задано, то должно быть установлено в Истина свойство НачальноеЗаполнение (см. далее).
      \n

      Процедура (Строка) – идентификатор процедуры, содержащий полный путь к процедуре-обработчику обновления.
      Например, \"Справочник.Валюты.ЗаполнитьКодДляПоиска\".

      \n

      НачальноеЗаполнение (Булево) – если Истина, то обработчик будет вызван при первом запуске пустой информационной базы (версия «0.0.0.0»), созданной из файла поставки конфигурации и не содержащей данных.
      Это обработчики первоначального заполнения базы.

      \n

      РежимВыполнения (Строка) – принимает одно из значений: \"Монопольно\", \"Оперативно\" и \"Отложенно\". Если свойство не задано, то по умолчанию обработчик – монопольный.

      \n
        \n
      • Монопольно – если обработчик обновления необходимо выполнять монопольно, в условиях отсутствия активных сеансов работы пользователей, регламентных заданий, внешних соединений и подключений по веб-сервисам. В противном случае, обновление версии программы прерывается. Подробнее см. Ограничения на использование монопольного режима обработчиков обновления

        Монопольные обработчики предназначены для обновления тех данных, обработка которых должна быть обязательно завершена к моменту входа пользователей в программу. Для сокращения времени простоя (ожидания обработки данных), рекомендуется большие объемы данных обновлять отложенно (см. ниже).
        Примеры монопольных обработчиков: обработка небольшого объема данных текущего периода, активных позиций номенклатуры и т.п.

        Если хотя бы один обработчик обновления конфигурации – монопольный, то все оперативные обработчики (см. далее) выполняются в монопольном режиме.

        В случае если обработчик обновления – обязательный (свойство Версия = «*»), то значение Монопольно следует устанавливать только в тех случаях, когда обработчик обновления должен программно определить, требуется ли монопольный режим для его выполнения: \n
          \n
        • Такой обработчик вызывается дважды, в него передается параметр Параметры типа Структура, в котором имеется свойство МонопольныйРежим (Булево) \n
        • При первом вызове в режиме проверки, свойство МонопольныйРежим содержит значение Ложь. \n
            \n
          • Код обработчика не должен модифицировать данные ИБ \n
          • Если в ходе выполнения обработчика возникает необходимость внесения изменений в ИБ, обработчик должен установить значение свойства в Истина и прекратить свое выполнение
          \n
        • При втором вызове в режиме выполнения свойство МонопольныйРежим содержит значение Истина \n
            \n
          • Код обработчик может модифицировать данные ИБ \n
          • Изменение значения свойства в этом случае игнорируется
        \n
      • Оперативно – если обработчик обновления необходимо выполнять не монопольно: при активных сеансах работы пользователей, регламентных заданий, внешних соединений и подключений через веб-сервисы.

        Оперативные обработчики следует применять в редких случаях, когда важно сократить время ожидания пользователей при переходе на исправительные релизы, которые не содержат изменений в структуре данных, и обновление на которые должно выполняться динамически.

        Подробнее см. Оперативное обновление данных.
        \n
      • Отложенно – если обработчик обновления необходимо выполнять в фоне после того, как завершено выполнение монопольных (оперативных) обработчиков, и пользователям уже разрешен вход в программу.

        Отложенные обработчики предназначены для обработки той части данных ИБ, которые не препятствуют пользователям начинать свою работу с новой версией программы, не дожидаясь завершения обработки этих данных.

        Примеры отложенных обработчиков: обработка больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, различных данных, отключенных в данный момент функциональными опциями и т.п.

        Подробнее см. Отложенное обновление данных.

        Если в конфигурации (библиотеке) используется параллельный режим отложенного обновления (в процедуре ПриДобавленииПодсистемы свойство РежимВыполненияОтложенныхОбработчиков = \"Параллельно\"), то для написания отложенных обработчиков следует руководствоваться стандартом Параллельный режим отложенного обновления.
      \n

      Пример описания обработчика, для выполнения которого требуется монопольный режим:

      \n

      Обработчик = Обработчики.Добавить();
      Обработчик.РежимВыполнения = \"Монопольно\";
      Обработчик.Версия = \"11.1.0.0\";
      Обработчик.Процедура = \"Справочник.МойСправочник.ЗаполнитьКодДляПоиска\";

      \n

      Пример реализации обработчика в модуле менеджера Справочник.МойСправочник:

      \n

      // Обработчик обновления УТ 11.1.0.0
      //
      // Перебираются все элементы справочника, в которых не заполнен код для поиска,
      // и заполняется кодом справочника без лидирующих нулей и префиксов
      //
      Процедура ЗаполнитьКодДляПоиска() Экспорт
      ...

      \n

      2. Расположение обработчиков обновления

      \n

      2.1. Процедура-обработчик должна оформляться в виде экспортной процедуры.
      Располагать процедуру следует в модуле менеджера того объекта метаданных, обновление которого она выполняет.

      \n

      Пример:
      Если в справочник «Подразделения» добавили новый реквизит, который необходимо заполнить значением по умолчанию, то процедура-обработчик должна располагаться в модуле менеджера этого справочника.

      \n

      2.2. В некоторых случаях, когда невозможно соотнести обработчик с каким-то конкретным объектом метаданных, допустимо расположение процедуры-обработчика в серверном общем модуле, назначение которого по смыслу связано с выполняемой обработкой ИБ (например, процедуры обновления, связанные со складской функциональностью должны располагаться в общем модуле СкладСервер). При этом процедура должна располагаться в служебной части модуля, в подразделе «Обновление ИБ».

      \n

      3. Реализация обработчиков обновления

      \n

      3.1. К процедуре-обработчику предъявляются следующие требования:

      \n
        \n
      • \n
        Обработчик не должен содержать логики по интерактивному взаимодействию с пользователем.
        \n
      • В случае критической ошибки при обновлении, в обработчике необходимо вызывать исключение, которое приведет к остановке всей процедуры обновления. Остановка обновления информационной базы приведет к невозможности запуска до тех пор, пока причины ошибки не будут устранены. \n
      • \n
        Обработчик должен быть рассчитан на неоднократное выполнение. На одних и тех же данных результат выполнения обработчика должен быть идентичен при любом количестве вызовов этого обработчика (например, повторный запуск обработчика не должен приводить к дублированию данных в информационной базе).
        \n
      • В пределах одной версии (значение свойства Версия), работоспособность обработчика не должна ставиться в зависимость от очередности его выполнения. Если подобные зависимости проявляются, то такие обработчики необходимо объединять в один. \n
      • Если в конфигурации предусмотрены планы обмена РИБ с отборами, то  также нужно учитывать, что в обновляемом подчиненном узле РИБ могут быть неполные данные:  например, в нем имеются движения по регистру, а сам регистратор отсутствует. При этом обработчик обновления должен пропускать обновление таких данных.
      \n

      3.2. Обработчик обновления не должен содержать лишних, избыточных действий с данными – должен выполняться максимально быстро.

      \n

      3.2.1. Для этого необходимо отключать бизнес-логику при обработке данных. В большинстве случаев, с помощью установки признака ОбменДанными.Загрузка:

      \n

      ДокументОбъект.ОбменДанными.Загрузка = Истина;

      \n

      В отдельных случаях, для частичного отключения бизнес-логики допустимо предусмотреть дополнительный признак, например:

      \n

      ДокументОбъект.ДополнительныеСвойства.Вставить(\"ОтключитьМоюБизнесЛогику\");

      \n

      3.2.2. Для большинства обрабатываемых данных следует отключать регистрацию изменений на узлах планов обмена, чтобы избежать отправки всего объема обработанных данных во все узлы. Таким образом:

      \n
        \n
      • В распределенной информационной базе (РИБ) обработка данных должна выполняться независимо в каждом из узлов; \n
      • При обмене между произвольными конфигурациями (программами) обработка данных не должна приводить к их выгрузке в базы-получатели.
      \n

      Исключение составляют случаи создания ссылочных объектов, которые должны быть перенесены механизмами обмена данными в другие узлы РИБ с тем же значением реквизита Ссылка.

      \n

      3.2.3. Таким образом, в коде обработчика обновления вместо

      \n

      ДокументОбъект.Записать();

      \n

      должно быть:

      \n

      ДокументОбъект.ОбменДанными.Загрузка = Истина; // отключить всю бизнес-логику при записи
      ДокументОбъект.ДополнительныеСвойства.Вставить(\"ОтключитьМеханизмРегистрацииОбъектов\");
      ДокументОбъект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
      ДокументОбъект.Записать();

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше следует использовать процедуру ЗаписатьДанные общего модуля ОбновлениеИнформационнойБазы:

      \n

      ОбновлениеИнформационнойБазы.ЗаписатьДанные(ДокументОбъект);

      \n

      3.3. Перед процедурой-обработчиком должен быть комментарий. При этом первая строка комментария должна содержать информацию о версии конфигурации, для которой предназначен этот обработчик. Последующие строки комментария должны содержать ответ на следующие вопросы:

      \n
        \n
      • \n
        Какие данные будут изменены (что меняем)?
        \n
      • \n
        Какие изменения будут внесены в эти данные (как меняем)?
      \n

      Пример:

      \n

      // Обработчик обновления УТ 11.1.0.0
      //
      // Перебираются все элементы справочника, в которых не заполнен код для поиска,
      // и заполняется кодом справочника без лидирующих нулей и префиксов
      //
      Процедура ЗаполнитьКодДляПоиска() Экспорт

      \n

      4. Переход на новые версии библиотек

      \n

      4.1. При постановке конфигурации на поддержку к новой версии библиотеки, следует увеличивать номер версии конфигурации. Это необходимо для запуска обработчиков обновления информационной базы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1365", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Разделитель пути файла указан вручную (необходимо использовать метод \"ПолучитьРазделительПути()\").", +"Description": "

      Особенности разработки конфигураций для ОС Linux и macOS

      #std723

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В большинстве случаев, в конфигурации не требуется предпринимать каких-либо специальных мер для обеспечения работы конфигурации (клиентское приложение и сервер) на ОС Linux и macOS. В этой статье перечислены отдельные рекомендации для специфических случаев, описанных в приложении 7 документации по платформе 1С:Предприятие.

      \n

      2. Для реализации всех ключевых функций прикладного решения следует использовать возможности платформы 1С:Предприятие по унификации работы на различных операционных системах.

      \n

      2.1. Вместо Windows-технологии COM (объект COMОбъект) следует использовать специализированные кроссплатформенные механизмы платформы:

      \n
        \n
      • Для администрирования кластера серверов 1С:Предприятия, вместо работы с объектной моделью агента сервера через COM-объект v83.ComConnector, следует использовать сервер администрирования (ras) и утилиту администрирования (rac). При работе в macOS утилиты rac и ras недоступны. \n
      • Для получения путей к рабочим каталогам, вместо COM-объектов ОС Windows, следует использовать методы глобального контекста РабочийКаталогДанныхПользователя, КаталогДокументов, КаталогВременныхФайлов.
      \n

      В остальных случаях следует рассмотреть другие альтернативы технологии COM, работающие в ОС Linux и macOS, например, технологию создания внешних компонент Native API.

      \n

      2.2. Внешние компоненты (клиентские и серверные), поставляемые в составе конфигурации, следует разрабатывать с использованием технологии Native API. Это позволяет создавать кроссплатформенные внешние компоненты для различных операционных систем, а также для веб-клиента, работающего в веб-браузерах, которые поддерживаются платформой 1С:Предприятие. Подробнее о разработке внешних компонент см. документацию по платформе.

      \n

      2.3. Для механизмов, использующих объект Почта, следует рассмотреть альтернативные варианты:

      \n
        \n
      • По переводу на объект ИнтернетПочта; \n
      • По разработке внешних компонент для ОС Linux и macOS, которые поддерживают работу с установленными почтовыми клиентами в ОС Linux и macOS.
      \n

      2.4. Если в составе конфигурации поставляются картинки в форматах WMF и EMF (метафайлы Windows), их следует заменить на растровые, например PNG или JPG.

      \n

      2.5. Также следует использовать возможности платформы 1С:Предприятие по унификации работы с файловой системой.

      \n

      2.5.1. В ОС Linux имена файлов регистро-зависимые, поэтому во всех местах кода, который работает с конкретным файлом, его имя (путь) должен указываться в одном регистре.

      \n

      2.5.2. Не следует указывать разделить пути файла и маску всех файлов вручную (например, «/», «*.*»), для этого необходимо использовать функции ПолучитьРазделительПути и ПолучитьМаскуВсеФайлы.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем для работы с именами файлов также рекомендуется использовать функции общих модулей ОбщегоНазначения и ОбщегоНазначенияКлиент.

      \n

      3. Для отдельных второстепенных (сервисных) функций прикладного решения допустимо отключать их работу в ОС Linux и macOS. Например, для прикладного решения в области торгового учета второстепенными могут считаться возможности по синхронизации данных через прямое подключение с другими программами, по импорту почты из сторонних почтовых клиентов и т.п.

      \n

      Для этого следует скрывать команды таких механизмов из командного интерфейса программы при работе в ОС Linux и macOS, либо (если технически скрыть невозможно) выводить сообщение вида
      «<Операция> доступна только при работе в ОС Windows».

      \n

      Например:

      \n

      &НаКлиенте
      Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
          Информация = Новый СистемнаяИнформация;
          Если Информация.ТипПлатформы <> ТипПлатформы.Windows_x86 И Информация.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
              ПоказатьПредупреждение(, НСтр(\"ru = 'Печать в Microsoft Word доступна только при работе в ОС Windows.'\"));
              Возврат;
          КонецЕсли;
         
          <...>
      КонецПроцедуры

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем рекомендуется использовать функции ЭтоLinuxКлиент, ЭтоMacOSКлиент и ЭтоWindowsКлиент из общих модулей ОбщегоНазначения и ОбщегоНазначенияКлиент.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1366", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Маска всех файлов указана вручную (необходимо использовать метод \"ПолучитьМаскуВсеФайлы()\").", +"Description": "

      Особенности разработки конфигураций для ОС Linux и macOS

      #std723

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В большинстве случаев, в конфигурации не требуется предпринимать каких-либо специальных мер для обеспечения работы конфигурации (клиентское приложение и сервер) на ОС Linux и macOS. В этой статье перечислены отдельные рекомендации для специфических случаев, описанных в приложении 7 документации по платформе 1С:Предприятие.

      \n

      2. Для реализации всех ключевых функций прикладного решения следует использовать возможности платформы 1С:Предприятие по унификации работы на различных операционных системах.

      \n

      2.1. Вместо Windows-технологии COM (объект COMОбъект) следует использовать специализированные кроссплатформенные механизмы платформы:

      \n
        \n
      • Для администрирования кластера серверов 1С:Предприятия, вместо работы с объектной моделью агента сервера через COM-объект v83.ComConnector, следует использовать сервер администрирования (ras) и утилиту администрирования (rac). При работе в macOS утилиты rac и ras недоступны. \n
      • Для получения путей к рабочим каталогам, вместо COM-объектов ОС Windows, следует использовать методы глобального контекста РабочийКаталогДанныхПользователя, КаталогДокументов, КаталогВременныхФайлов.
      \n

      В остальных случаях следует рассмотреть другие альтернативы технологии COM, работающие в ОС Linux и macOS, например, технологию создания внешних компонент Native API.

      \n

      2.2. Внешние компоненты (клиентские и серверные), поставляемые в составе конфигурации, следует разрабатывать с использованием технологии Native API. Это позволяет создавать кроссплатформенные внешние компоненты для различных операционных систем, а также для веб-клиента, работающего в веб-браузерах, которые поддерживаются платформой 1С:Предприятие. Подробнее о разработке внешних компонент см. документацию по платформе.

      \n

      2.3. Для механизмов, использующих объект Почта, следует рассмотреть альтернативные варианты:

      \n
        \n
      • По переводу на объект ИнтернетПочта; \n
      • По разработке внешних компонент для ОС Linux и macOS, которые поддерживают работу с установленными почтовыми клиентами в ОС Linux и macOS.
      \n

      2.4. Если в составе конфигурации поставляются картинки в форматах WMF и EMF (метафайлы Windows), их следует заменить на растровые, например PNG или JPG.

      \n

      2.5. Также следует использовать возможности платформы 1С:Предприятие по унификации работы с файловой системой.

      \n

      2.5.1. В ОС Linux имена файлов регистро-зависимые, поэтому во всех местах кода, который работает с конкретным файлом, его имя (путь) должен указываться в одном регистре.

      \n

      2.5.2. Не следует указывать разделить пути файла и маску всех файлов вручную (например, «/», «*.*»), для этого необходимо использовать функции ПолучитьРазделительПути и ПолучитьМаскуВсеФайлы.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем для работы с именами файлов также рекомендуется использовать функции общих модулей ОбщегоНазначения и ОбщегоНазначенияКлиент.

      \n

      3. Для отдельных второстепенных (сервисных) функций прикладного решения допустимо отключать их работу в ОС Linux и macOS. Например, для прикладного решения в области торгового учета второстепенными могут считаться возможности по синхронизации данных через прямое подключение с другими программами, по импорту почты из сторонних почтовых клиентов и т.п.

      \n

      Для этого следует скрывать команды таких механизмов из командного интерфейса программы при работе в ОС Linux и macOS, либо (если технически скрыть невозможно) выводить сообщение вида
      «<Операция> доступна только при работе в ОС Windows».

      \n

      Например:

      \n

      &НаКлиенте
      Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
          Информация = Новый СистемнаяИнформация;
          Если Информация.ТипПлатформы <> ТипПлатформы.Windows_x86 И Информация.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
              ПоказатьПредупреждение(, НСтр(\"ru = 'Печать в Microsoft Word доступна только при работе в ОС Windows.'\"));
              Возврат;
          КонецЕсли;
         
          <...>
      КонецПроцедуры

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем рекомендуется использовать функции ЭтоLinuxКлиент, ЭтоMacOSКлиент и ЭтоWindowsКлиент из общих модулей ОбщегоНазначения и ОбщегоНазначенияКлиент.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1367", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует локализация при форматировании даты.", +"Description": "

      Форматирование даты, числа, Булево: требования по локализации

      #std763

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При использовании функции Формат в некоторых случаях следует использовать функцию НСтр при создании форматной строки (формат представления или редактирования дат, Булево значения и т.п.) . При этом форматная строка, задаваемая в свойствах метаданных (форм), подлежит локализации всегда, также, как синоним.

      \n

      1.1. Форматирование дат

      \n

      для вывода дат следует учитывать, что в различных странах приняты различные порядок следования и разделители для составных частей даты.

      \n

      Например, одна и та же дата: 20.12.2012 – для России, 12/20/2012 – для США.

      \n

      Поэтому вместо явного задания формата даты рекомендуется использовать локальный формат даты (ДЛФ).

      \n

      В случаях, когда использовать локальный формат даты не получатся, и требуется задать произвольный формат (ДФ) или указать представление пустой даты (ДП) нужно применять функцию НСтр к форматной строке, чтобы при локализации оставалась возможность переопределить выводимый формат:

      \n

      Неправильно:

      Формат(ДатаУтверждения, \"ДФ=дд.ММ.гггг\");\nФормат(ДатаУтверждения, \"ДФ=ММММ гггг\") + \" г.\";\n
      \n

      Правильно:

      Формат(ДатаУтверждения, \"ДЛФ=ДД\");\nФормат(ДатаУтверждения, НСтр(\"ru='ДФ=ММММ гггг \"\"г.\"\"'\");\n
      \n

      1.2. Форматирование числа

      \n

      Следует применять функцию НСтр к форматной строке в случае, когда
      • для числа задается нечисловое представление нулевого значения (ЧН) ;
      • указан шаблон форматирования числа (ЧФ);
      • переопределяется разделитель дробной части (ЧРД).

      \n

      Неправильно:

      Предупреждение(Формат(100, \"ЧН=Отсутствует\"));\nПредупреждение(Формат(100, \"ЧФ=\"\"$Ч' / Час'\"\"\"));\n
      \n

      Правильно:

      Предупреждение(Формат(100, НСтр(\"ru = 'ЧН=Отсутствует'\")));\nПредупреждение(Формат(100, НСтр(\"ru = 'ЧФ=\"\"$Ч'' / Час''\"\"'\"))); // \"$100 / Час\"\n
      \n

      1.3. Форматирование Булево

      \n

      Для вывода Булево значения пользователю всегда применяйте функцию НСтр к форматной строке.

      \n

      Неправильно:

      Предупреждение(Формат(Истина, \"БЛ=Нет; БИ=Да\"));\n
      \n

      Правильно:

      Предупреждение(Формат(Истина, НСтр(\"ru='БЛ=Нет; БИ=Да'\")));\n
      \n

      1.4. Не следует переопределять поведение отображения локализации данных по умолчанию – формат отображения операционной системы. При использовании функции Формат следует избегать использовать параметр «L=».

      \n

      2. При задании формата в полях ввода в формах и полях отчетов на базе СКД также рекомендуется локальный формат даты. Использовать другие форматы допустимо, если по сути решаемой задачи локальный формат не подходит – тогда форматная строка будет переводиться при переводе конфигурации.

      \n

      3. При переопределении стандартных представлений полей в отчетах на базе СКД следует придерживаться тех же правил, что и в коде модулей. Например, неправильно:

      \n

      \"N \" + ВОтветНаНомер + \" от \" + Формат(ВОтветНаДата, \"ДФ=dd.MM.yyyy\")

      \n

      правильное выражение, по которому вычисляется представление поля:

      СтрШаблон(\n  НСтр(\"ru = 'N%1 от %2'\"),\n  ВОтветНаНомер,\n  Формат(ВОтветНаДата, \"ДЛФ=D\"))\n
      \n

      4. В случае, когда требуется передача значения в машиночитаемом виде, вне зависимости от информационной системы и настроек локализации, применяемых в ней, вместо локализации значения следует выполнить сериализацию. Локализацию дат нужно использовать всегда, когда это возможно. В тех случаях, когда это технически нецелесообразно, допускается отказываться от локализации. Например, при генерации файла формата XML, поддерживаемого банк-клиентом системы, специфичной для России.

      \n

      В общем случае для сериализации рекомендуется использовать метод XMLСтрока.

      \n

      Для десериализации XMLЗначение. Или метод ПривестиЗначение объекта ОписаниеТипов.

      \n

      4.1. Сериализация дат

      \n

      При разработке собственных форматов передачи данных между различными системами рекомендуется сериализовать дату в формате ISO: \"ГГГГ-ММ-ДДTЧЧ:ММ:ССZ\", например \"2009-02-15T00:00:00Z\" (соответствует типу dateTime схемы XML см. http://www.w3.org/TR/xmlschema-2/#dateTime).

      \n

      Неправильно:

      \n

      Строка = Формат(Дата, \"ДФ=гггг-ММ-ддTЧЧ:мм:сс\"); // Сериализация

      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Дата); // Сериализация\n// Или\nСтрока = ЗаписатьДатуJSON(Дата, ФорматДатыJSON.ISO); // Сериализация\nОписаниеТипа = Новый ОписаниеТипов(\"Дата\");\nДата = ОписаниеТипа.ПривестиЗначение(Строка);
      // Десериализация\nДата = XMLЗначение(Тип(\"Дата\"), Строка); \n// Или\nДата = ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO);\n
      \n

      4.2. Сериализация числа

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Число);\n// Или\nСтрока = Формат(Число);\n
      \n

      Правильно:

      \n

      Строка = XMLСтрока(Число); // Сериализация
      Число = XMLЗначение(Тип(\"Число\"), Строка); // Десериализация

      \n

      4.3. Сериализация Булево

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Булево);\n// Или\nСтрока = Формат(Булево);\n// Или\nСтрока = Формат(Булево, \"БЛ=off; БИ=on\");
      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Булево);\n// Или\nБулево = XMLЗначение(Тип(\"Булево \"), Строка);\n// Или\nСтрока = ?(Булево, \"on\", \"off\");\n
      \n


      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1368", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует локализация при форматировании числа.", +"Description": "

      Форматирование даты, числа, Булево: требования по локализации

      #std763

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При использовании функции Формат в некоторых случаях следует использовать функцию НСтр при создании форматной строки (формат представления или редактирования дат, Булево значения и т.п.) . При этом форматная строка, задаваемая в свойствах метаданных (форм), подлежит локализации всегда, также, как синоним.

      \n

      1.1. Форматирование дат

      \n

      для вывода дат следует учитывать, что в различных странах приняты различные порядок следования и разделители для составных частей даты.

      \n

      Например, одна и та же дата: 20.12.2012 – для России, 12/20/2012 – для США.

      \n

      Поэтому вместо явного задания формата даты рекомендуется использовать локальный формат даты (ДЛФ).

      \n

      В случаях, когда использовать локальный формат даты не получатся, и требуется задать произвольный формат (ДФ) или указать представление пустой даты (ДП) нужно применять функцию НСтр к форматной строке, чтобы при локализации оставалась возможность переопределить выводимый формат:

      \n

      Неправильно:

      Формат(ДатаУтверждения, \"ДФ=дд.ММ.гггг\");\nФормат(ДатаУтверждения, \"ДФ=ММММ гггг\") + \" г.\";\n
      \n

      Правильно:

      Формат(ДатаУтверждения, \"ДЛФ=ДД\");\nФормат(ДатаУтверждения, НСтр(\"ru='ДФ=ММММ гггг \"\"г.\"\"'\");\n
      \n

      1.2. Форматирование числа

      \n

      Следует применять функцию НСтр к форматной строке в случае, когда
      • для числа задается нечисловое представление нулевого значения (ЧН) ;
      • указан шаблон форматирования числа (ЧФ);
      • переопределяется разделитель дробной части (ЧРД).

      \n

      Неправильно:

      Предупреждение(Формат(100, \"ЧН=Отсутствует\"));\nПредупреждение(Формат(100, \"ЧФ=\"\"$Ч' / Час'\"\"\"));\n
      \n

      Правильно:

      Предупреждение(Формат(100, НСтр(\"ru = 'ЧН=Отсутствует'\")));\nПредупреждение(Формат(100, НСтр(\"ru = 'ЧФ=\"\"$Ч'' / Час''\"\"'\"))); // \"$100 / Час\"\n
      \n

      1.3. Форматирование Булево

      \n

      Для вывода Булево значения пользователю всегда применяйте функцию НСтр к форматной строке.

      \n

      Неправильно:

      Предупреждение(Формат(Истина, \"БЛ=Нет; БИ=Да\"));\n
      \n

      Правильно:

      Предупреждение(Формат(Истина, НСтр(\"ru='БЛ=Нет; БИ=Да'\")));\n
      \n

      1.4. Не следует переопределять поведение отображения локализации данных по умолчанию – формат отображения операционной системы. При использовании функции Формат следует избегать использовать параметр «L=».

      \n

      2. При задании формата в полях ввода в формах и полях отчетов на базе СКД также рекомендуется локальный формат даты. Использовать другие форматы допустимо, если по сути решаемой задачи локальный формат не подходит – тогда форматная строка будет переводиться при переводе конфигурации.

      \n

      3. При переопределении стандартных представлений полей в отчетах на базе СКД следует придерживаться тех же правил, что и в коде модулей. Например, неправильно:

      \n

      \"N \" + ВОтветНаНомер + \" от \" + Формат(ВОтветНаДата, \"ДФ=dd.MM.yyyy\")

      \n

      правильное выражение, по которому вычисляется представление поля:

      СтрШаблон(\n  НСтр(\"ru = 'N%1 от %2'\"),\n  ВОтветНаНомер,\n  Формат(ВОтветНаДата, \"ДЛФ=D\"))\n
      \n

      4. В случае, когда требуется передача значения в машиночитаемом виде, вне зависимости от информационной системы и настроек локализации, применяемых в ней, вместо локализации значения следует выполнить сериализацию. Локализацию дат нужно использовать всегда, когда это возможно. В тех случаях, когда это технически нецелесообразно, допускается отказываться от локализации. Например, при генерации файла формата XML, поддерживаемого банк-клиентом системы, специфичной для России.

      \n

      В общем случае для сериализации рекомендуется использовать метод XMLСтрока.

      \n

      Для десериализации XMLЗначение. Или метод ПривестиЗначение объекта ОписаниеТипов.

      \n

      4.1. Сериализация дат

      \n

      При разработке собственных форматов передачи данных между различными системами рекомендуется сериализовать дату в формате ISO: \"ГГГГ-ММ-ДДTЧЧ:ММ:ССZ\", например \"2009-02-15T00:00:00Z\" (соответствует типу dateTime схемы XML см. http://www.w3.org/TR/xmlschema-2/#dateTime).

      \n

      Неправильно:

      \n

      Строка = Формат(Дата, \"ДФ=гггг-ММ-ддTЧЧ:мм:сс\"); // Сериализация

      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Дата); // Сериализация\n// Или\nСтрока = ЗаписатьДатуJSON(Дата, ФорматДатыJSON.ISO); // Сериализация\nОписаниеТипа = Новый ОписаниеТипов(\"Дата\");\nДата = ОписаниеТипа.ПривестиЗначение(Строка);
      // Десериализация\nДата = XMLЗначение(Тип(\"Дата\"), Строка); \n// Или\nДата = ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO);\n
      \n

      4.2. Сериализация числа

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Число);\n// Или\nСтрока = Формат(Число);\n
      \n

      Правильно:

      \n

      Строка = XMLСтрока(Число); // Сериализация
      Число = XMLЗначение(Тип(\"Число\"), Строка); // Десериализация

      \n

      4.3. Сериализация Булево

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Булево);\n// Или\nСтрока = Формат(Булево);\n// Или\nСтрока = Формат(Булево, \"БЛ=off; БИ=on\");
      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Булево);\n// Или\nБулево = XMLЗначение(Тип(\"Булево \"), Строка);\n// Или\nСтрока = ?(Булево, \"on\", \"off\");\n
      \n


      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1369", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует локализация при форматировании Булево.", +"Description": "

      Форматирование даты, числа, Булево: требования по локализации

      #std763

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При использовании функции Формат в некоторых случаях следует использовать функцию НСтр при создании форматной строки (формат представления или редактирования дат, Булево значения и т.п.) . При этом форматная строка, задаваемая в свойствах метаданных (форм), подлежит локализации всегда, также, как синоним.

      \n

      1.1. Форматирование дат

      \n

      для вывода дат следует учитывать, что в различных странах приняты различные порядок следования и разделители для составных частей даты.

      \n

      Например, одна и та же дата: 20.12.2012 – для России, 12/20/2012 – для США.

      \n

      Поэтому вместо явного задания формата даты рекомендуется использовать локальный формат даты (ДЛФ).

      \n

      В случаях, когда использовать локальный формат даты не получатся, и требуется задать произвольный формат (ДФ) или указать представление пустой даты (ДП) нужно применять функцию НСтр к форматной строке, чтобы при локализации оставалась возможность переопределить выводимый формат:

      \n

      Неправильно:

      Формат(ДатаУтверждения, \"ДФ=дд.ММ.гггг\");\nФормат(ДатаУтверждения, \"ДФ=ММММ гггг\") + \" г.\";\n
      \n

      Правильно:

      Формат(ДатаУтверждения, \"ДЛФ=ДД\");\nФормат(ДатаУтверждения, НСтр(\"ru='ДФ=ММММ гггг \"\"г.\"\"'\");\n
      \n

      1.2. Форматирование числа

      \n

      Следует применять функцию НСтр к форматной строке в случае, когда
      • для числа задается нечисловое представление нулевого значения (ЧН) ;
      • указан шаблон форматирования числа (ЧФ);
      • переопределяется разделитель дробной части (ЧРД).

      \n

      Неправильно:

      Предупреждение(Формат(100, \"ЧН=Отсутствует\"));\nПредупреждение(Формат(100, \"ЧФ=\"\"$Ч' / Час'\"\"\"));\n
      \n

      Правильно:

      Предупреждение(Формат(100, НСтр(\"ru = 'ЧН=Отсутствует'\")));\nПредупреждение(Формат(100, НСтр(\"ru = 'ЧФ=\"\"$Ч'' / Час''\"\"'\"))); // \"$100 / Час\"\n
      \n

      1.3. Форматирование Булево

      \n

      Для вывода Булево значения пользователю всегда применяйте функцию НСтр к форматной строке.

      \n

      Неправильно:

      Предупреждение(Формат(Истина, \"БЛ=Нет; БИ=Да\"));\n
      \n

      Правильно:

      Предупреждение(Формат(Истина, НСтр(\"ru='БЛ=Нет; БИ=Да'\")));\n
      \n

      1.4. Не следует переопределять поведение отображения локализации данных по умолчанию – формат отображения операционной системы. При использовании функции Формат следует избегать использовать параметр «L=».

      \n

      2. При задании формата в полях ввода в формах и полях отчетов на базе СКД также рекомендуется локальный формат даты. Использовать другие форматы допустимо, если по сути решаемой задачи локальный формат не подходит – тогда форматная строка будет переводиться при переводе конфигурации.

      \n

      3. При переопределении стандартных представлений полей в отчетах на базе СКД следует придерживаться тех же правил, что и в коде модулей. Например, неправильно:

      \n

      \"N \" + ВОтветНаНомер + \" от \" + Формат(ВОтветНаДата, \"ДФ=dd.MM.yyyy\")

      \n

      правильное выражение, по которому вычисляется представление поля:

      СтрШаблон(\n  НСтр(\"ru = 'N%1 от %2'\"),\n  ВОтветНаНомер,\n  Формат(ВОтветНаДата, \"ДЛФ=D\"))\n
      \n

      4. В случае, когда требуется передача значения в машиночитаемом виде, вне зависимости от информационной системы и настроек локализации, применяемых в ней, вместо локализации значения следует выполнить сериализацию. Локализацию дат нужно использовать всегда, когда это возможно. В тех случаях, когда это технически нецелесообразно, допускается отказываться от локализации. Например, при генерации файла формата XML, поддерживаемого банк-клиентом системы, специфичной для России.

      \n

      В общем случае для сериализации рекомендуется использовать метод XMLСтрока.

      \n

      Для десериализации XMLЗначение. Или метод ПривестиЗначение объекта ОписаниеТипов.

      \n

      4.1. Сериализация дат

      \n

      При разработке собственных форматов передачи данных между различными системами рекомендуется сериализовать дату в формате ISO: \"ГГГГ-ММ-ДДTЧЧ:ММ:ССZ\", например \"2009-02-15T00:00:00Z\" (соответствует типу dateTime схемы XML см. http://www.w3.org/TR/xmlschema-2/#dateTime).

      \n

      Неправильно:

      \n

      Строка = Формат(Дата, \"ДФ=гггг-ММ-ддTЧЧ:мм:сс\"); // Сериализация

      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Дата); // Сериализация\n// Или\nСтрока = ЗаписатьДатуJSON(Дата, ФорматДатыJSON.ISO); // Сериализация\nОписаниеТипа = Новый ОписаниеТипов(\"Дата\");\nДата = ОписаниеТипа.ПривестиЗначение(Строка);
      // Десериализация\nДата = XMLЗначение(Тип(\"Дата\"), Строка); \n// Или\nДата = ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO);\n
      \n

      4.2. Сериализация числа

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Число);\n// Или\nСтрока = Формат(Число);\n
      \n

      Правильно:

      \n

      Строка = XMLСтрока(Число); // Сериализация
      Число = XMLЗначение(Тип(\"Число\"), Строка); // Десериализация

      \n

      4.3. Сериализация Булево

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Булево);\n// Или\nСтрока = Формат(Булево);\n// Или\nСтрока = Формат(Булево, \"БЛ=off; БИ=on\");
      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Булево);\n// Или\nБулево = XMLЗначение(Тип(\"Булево \"), Строка);\n// Или\nСтрока = ?(Булево, \"on\", \"off\");\n
      \n


      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "137", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не рекомендуются длительные вызовы из клиентского кода в серверный.", +"Description": "

      Длительные операции на сервере

      #std642

      Область применения: управляемое приложение.

      \n

      1. При разработке конфигураций следует избегать длительных вызовов из клиентского кода в серверный. Все длительные серверные вызовы, которые могут выполняться более 8 секунд в обычных сценариях работы пользователя, следует выполнять асинхронно, с помощью фонового задания.

      \n

      К таким операциям относятся: формирование отчета, групповая обработка объектов, загрузка или выгрузка данных в другое приложение, заполнение больших табличных частей и т.п.

      \n

      В противном случае такие вызовы могут привести к потере работоспособности приложения или затруднению работы с ним:

      \n
        \n
      • браузер может предложить прекратить длительно выполняющийся сценарий, после чего приложение станет неработоспособным; \n
      • веб сервер может прервать длительное обращение к серверу 1С:Предприятия и вернуть ошибку 504 (шлюз не отвечает); \n
      • в случае длительного выполнения операции, у пользователя нет возможности отменить ее.
      \n

      2.1. Общий подход к асинхронному выполнению длительных серверных операций с помощью фонового задания:

      \n
        \n
      • Код, выполняющий длительную обработку данных, располагается в модуле менеджера объекта* или в общем модуле. Результат своей работы он помещает во временное хранилище;

        *Примечание: необходимо использовать процедуру-обертку в общем модуле, которая будет вызывать процедуру модуля менеджера через ОбщегоНазначения.ВыполнитьМетодКонфигурации(). Т.к. фоновые задания могут работать только с процедурами и функциями общих модулей.
        \n
      • Для выполнения этого кода на сервере запускается фоновое задание, при этом необходимо ожидать завершения выполнения фонового задания в течение 0.8 сек; \n
      • Если за время ожидания выполнения задания оно не завершилось, то управление возвращается на клиент, и в клиентском коде подключается обработчик ожидания, в котором периодически проверяется состояние фонового задания. При этом интервал опроса задания увеличивается от 1 до 15 секунд с фиксированным коэффициентом 1.4; \n
      • На время выполнения длительной операции пользователю отображается индикатор;
        при этом для отчетов индикатор выводится в поле табличного документа, используя свойство поля табличного документа ОтображениеСостояния:



        а для прочих мест – выводится блокирующая форма (РежимОткрытияОкна = БлокироватьОкноВладельца), на которой размещена декорация с анимированной картинкой и кнопка «Отмена»:


        \n
      • При получении от сервера информации о том, что фоновое задание завершено, полученный результат загружается из временного хранилища и обрабатывается.
      \n

      2.2. Асинхронное формирование отчета требуется только для тех отчетов, которые 

      \n
        \n
      • разработаны без использования СКД или с использованием СКД, но с переопределенной процедурой формирования отчета (переопределен обработчик кнопки «Сформировать» или в обработчике модуля отчета ПриКомпоновкеРезультата устанавливается СтандартнаяОбработка = Ложь). \n
      • и формирование которых, как правило, занимает длительное время.
      \n

      Поведение таких отчетов должно быть максимально похожим на поведение отчетов на базе СКД, а именно:

      \n
        \n
      • форму отчета не следует блокировать на время его формирования;  \n
      • пользователь может изменить настройки и переформировать отчет, не дожидаясь окончания его формирования; \n
      • при закрытии формы отчета, формирование отчета прерывается.
      \n

      3. При использовании в конфигурации Библиотеки стандартных подсистем в распоряжении разработчика имеются вспомогательные функции и процедуры общих модулей ДлительныеОперации, ДлительныеОперацииКлиент, а также процедура УстановитьСостояниеПоляТабличногоДокумента общего модуля ОбщегоНазначенияКлиентСервер.

      \n

      Пример выполнения функции в фоновом задании при использовании в конфигурации Библиотеки стандартных подсистем. В модуле менеджера объекта размещена функция, которая выполняет поиск настроек и возвращает их:

      \n

      Функция ОпределитьНастройкиУчетнойЗаписи(АдресЭлектроннойПочты, Пароль) Экспорт
       ...
       Возврат Настройки;
      КонецФункции

      \n

      В форме объекта выполняется вызов этой функции в фоновом задании в три этапа:
      1) запуск фонового задания на сервере,
      2) подключение обработчика завершения фонового задания на клиенте,
      3) обработка результата выполнения фонового задания.

      \n

      &НаКлиенте
      Процедура НастроитьПараметрыПодключенияАвтоматически()
       // 1. Запуск фонового задания на сервере.
       ДлительнаяОперация = НачатьПоискНастроекУчетнойЗаписи();
       
       // 2. Подключение обработчика завершения фонового задания.
       ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
       Оповещение = Новый ОписаниеОповещения(\"ПриЗавершенииПоискаНастроек\", ЭтотОбъект);
       ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания);
      КонецПроцедуры

      \n

      &НаСервере
      Функция НачатьПоискНастроекУчетнойЗаписи()
       ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
       Возврат ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, \"Справочники.УчетныеЗаписиЭлектроннойПочты.ОпределитьНастройкиУчетнойЗаписи\",
        АдресЭлектроннойПочты, Пароль);
      КонецФункции

      \n

      // 3. Обработка результата выполнения фонового задания.
      &НаКлиенте
      Процедура ПриЗавершенииПоискаНастроек(Результат, ДополнительныеПараметры) Экспорт

      \n

       Если Результат = Неопределено Тогда // Пользователь отменил задание.
        Возврат;
       КонецЕсли;
       
       Если Результат.Статус = \"Ошибка\" Тогда
        ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
       КонецЕсли;
       
       Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
       УстановитьНастройкиУчетнойЗаписи(Настройки);
       
      КонецПроцедуры

      \n

      4. Если в конфигурации реализуются алгоритмы, инициирующие запуск фоновых заданий или запись данных информационной базы без участия пользователя (например, регулярное обновление информации в открытой форме), то в них следует проверять, что в текущем сеансе не установлен монопольный режим. В противном случае, следует блокировать попытки выполнения таких действий. Например:

      \n

      Если МонопольныйРежим() Тогда
        Возврат;
      КонецЕсли;

      \n

      ФоновыеЗадания.Выполнить(\"...

      \n

      5. В некоторых случаях возникает необходимость в выполнении длительных операций, требующих установки монопольного режима доступа к информационной базе. Например:

      \n
        \n
      • \n
         Обновление данных ИБ при первом интерактивном запуске программы после обновления конфигурации;
        \n
      • \n
         Удаление объектов, помеченных на удаление;
        \n
      • \n
         Выгрузка данных информационной базы в файл для перехода в сервис;
        \n
      • \n
         Использования монопольного режима для снижения времени выполнения массовых операций по изменению данных;
      \n

      При этом необходимо сначала устанавливать монопольный режим, а затем выполнять запуск фонового задания, которое реализует саму длительную операцию. В этом случае фоновым заданием будет унаследован монопольный режим, ранее установленный из пользовательского сеанса (см. документацию к платформе).

      \n

      На время выполнения этого фонового задания следует блокировать весь интерфейс приложения, открывая форму ожидания завершения операции в режиме РежимОткрытияОкна = БлокироватьВесьИнтерфейс. Блокировать интерфейс приложения требуется потому, что на время выполнения задания полноценная работа пользователя с приложением уже невозможна:

      \n
        \n
      • Если пользователь(*) попытается записать какой-либо объект, это приведет к ошибке (из-за установленного монопольного режима); \n
      • В ряде случаев могут запускаться фоновые задания в качестве реакции на действия пользователя случае (при поиске в динамическом списке, при вводе по строке, формировании отчетов и пр.), которые также завершатся с ошибкой.
        Кроме того, на самой форме ожидания длительной операции не следует размещать элементы управления, которые могут приводить к запуску таких фоновых заданий. Например: поля ввода, динамические списки и отчеты.
      \n

      * Примечание: ошибки записи также возникают в тех случаях, когда объекты записываются программно, например, из обработчиков ожидания. В них также следует проверять монопольный режим согласно п.5.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1370", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В модуле устаревшего объекта содержится код.", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1371", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Устаревший объект включен в свойство другого объекта.", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1374", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Некорректное использование платформенного метода \"Тип()\".", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1375", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В правах роли установлены ограничения (RLS) для устаревшего объекта метаданных.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1377", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Разыменование ссылочного поля составного типа", +"Description": "

      Разыменование ссылочных полей составного типа в языке запросов

      #std654

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В языке запросов возможно обращаться не только к полям исходных таблиц запроса, перечисленных в предложении ИЗ, но и к полям таблицы, на которую ссылается поле исходной таблицы запроса, если это поле имеет ссылочный тип. Имена полей при этом пишутся \"через точку\". Применение такой конструкции приводит к неявному соединению с дополнительными таблицами для получения значений полей \"через точку\".

      \n

      Например, в запросе

      \n

      ВЫБРАТЬ
      ТоварныеЗапасы.Товар КАК Товар,
      ТоварныеЗапасы.Количество КАК Количество,
      ТоварныеЗапасы.Товар.Артикул КАК Артикул
      ИЗ
      РегистрНакопления.ТоварныеЗапасы КАК ТоварныеЗапасы
      ...

      \n

      кроме явно указанной в предложении ИЗ таблицы РегистрНакопления.ТоварныеЗапасы неявно участвует таблица Справочник.Товары для получения значения поля Артикул. А в случае использования ограничений доступа на уровне записей (RLS), к запросу добавляются ещё и таблицы, участвующие в RLS к таблице Справочник.Товары.

      \n

      1.2. Большое число исходных таблиц запроса приводит к его усложнению и может значительно увеличивать время его выполнения. Особенно это важно помнить в тех случаях, когда поле таблицы ссылочного типа имеет составной тип и может содержать ссылки на несколько таблиц. В таком случае, получение полей других таблиц \"через точку\" от такого поля составного типа приведет к соединениию со всеми таблицами, ссылки на которые могут оказаться в данном поле и в RLS к этим таблицам.

      \n

      Например, в приведенном ниже запросе получение даты регистратора приведет к неявному соединению с таблицами всех документов - регистраторов регистра ТоварныеЗапасы

      \n

      ВЫБРАТЬ
      ...
      ТоварныеЗапасы.Регистратор.Дата,
      ...
      ИЗ
      РегистрНакопления.ТоварныеЗапасы КАК ТоварныеЗапасы
      ...

      \n

      Подобное получение данных \"через точку\" от ссылочных полей составного типа крайне нежелательно. Каждое исключение из этого правила должно тщательно анализироваться.

      \n

      2.1. Следует избегать избыточности при создании полей составных ссылочных типов. Необходимо указывать ровно столько возможных типов для данного поля, сколько необходимо. Не следует без необходимости использовать типы \"любая ссылка\" или \"ссылка на любой документ\" и т.п.

      \n

      Вместо этого следует более тщательно проанализировать прикладную логику и назначить для поля ровно те возможные типы ссылок, которые необходимы для решения задачи.

      \n

      2.2. Для того чтобы избежать запросов с использованием большого числа исходных таблиц следует жертвовать компактностью хранения данных ради производительности и помещать соответствующие данные в исходную таблицу запроса.

      \n

      Например, в регистре ТоварныеЗапасы можно завести реквизит ДатаРегистратора, заполнять его при проведении документов и использовать затем в запросах:

      \n

      ВЫБРАТЬ
      ...
      ТоварныеЗапасы.ДатаРегистратора,
      ...
      ИЗ
      РегистрНакопления.ТоварныеЗапасы КАК ТоварныеЗапасы
      ...

      \n

      Это приведет к дублированию информации и некоторому (незначительному) увеличению ее объема, но может существенно повысить производительность и стабильность работы запроса.

      \n

      2.3. При необходимости следует жертвовать компактностью и универсальностью кода ради производительности:

      \n
        \n
      • Как правило, для выполнения конкретного запроса в данных условиях не нужны все возможные типы данной ссылки. В этом случае, следует ограничить количество возможных типов при помощи функции ВЫРАЗИТЬ. \n
      • Если данный запрос является универсальным и используется в нескольких разных ситуациях (где типы ссылки могут быть разными), то можно формировать запрос динамически, подставляя в функцию ВЫРАЗИТЬ тот тип, который необходим при данных условиях.
      \n

      Это увеличит объем исходного кода и, возможно, сделает его менее универсальным, но может существенно повысить производительность и стабильность работы запроса.

      \n

      Например, неправильно:

      \n

      Запрос.Текст = \"ВЫБРАТЬ
      | Продажи.Регистратор.Номер,
      | Продажи.Регистратор.Дата,
      | Продажи.Контрагент,
      | Продажи.Количество,
      | Продажи.Стоимость
      |ИЗ
      | РегистрНакопления.Продажи КАК Продажи
      |ГДЕ ... 

      \n

      В данном запросе используется обращение к реквизитам регистратора. Регистратор является полем составного типа, которое может принимать значения ссылки на один из 56 видов документов.  
      SQL-текст этого запроса будет включать 56 левых соединений с таблицами документов. Это может привести к серьезным проблемам производительности при выполнении запроса.

      \n

      Правильно:

      \n

      Для решения данной конкретной задачи нет необходимости соединяться со всеми 56 видами документов. Условия запроса таковы, что при его выполнении будут выбраны только движения документов РеализацияТоваровУслуг и ЗаказыПокупателя. В этом случае можно значительно ускорить работу запроса, ограничив количество соединений при помощи функции ВЫРАЗИТЬ().  

      \n

      Запрос.Текст = \"ВЫБРАТЬ
      | ВЫБОР
      | КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
      | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Номер
      | КОГДА Продажи.Регистратор ССЫЛКА Документ.ЗаказПокупателя
      | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.ЗаказПокупателя).Номер
      | КОНЕЦ ВЫБОРА КАК Номер,
      | ВЫБОР
      | КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
      | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата
      | КОГДА Продажи.Регистратор ССЫЛКА Документ.ЗаказПокупателя
      | ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.ЗаказПокупателя).Дата
      | КОНЕЦ ВЫБОРА КАК Дата,
      | Продажи.Контрагент,
      | Продажи.Количество,
      | Продажи.Стоимость
      |ИЗ
      | РегистрНакопления.Продажи КАК Продажи
      |ГДЕ
      | Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
      | ИЛИ Продажи.Регистратор ССЫЛКА Документ.ЗаказыПокупателя\"; 

      \n


      Этот запрос является более громоздким и, возможно, менее универсальным (он не будет правильно работать для других ситуаций - когда возможны другие значения типов регистратора). Однако, при его выполнении будет сформирован SQL запрос, который будет содержать всего два соединения с таблицами документов. Такой запрос будет работать значительно быстрее и стабильнее, чем запрос в его первоначальном виде.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "138", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не определена функция для создания новой структуры.", +"Description": "

      Особенности использования структур в качестве параметров процедур и функций

      #std641

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n
      \n

      Основная статья: Параметры процедур и функций 

      \n

      Для процедур и функций (далее по тексту: функций) с параметрами типа Структура рекомендуется придерживаться следующего подхода к разработке.

      \n

      1. Помимо функции, которая собственно реализует прикладную функциональность (далее по тексту: вызываемая функция), необходимо определить функцию-конструктор для создания новой структуры (далее по тексту функция-конструктор параметров). При этом сама функция-конструктор не принимает параметров, а только возвращает структуру-заготовку со свойствами, которую вызывающий код должен проинициализировать конкретными значениями и передать в вызываемую функцию.

      \n

      Пример вызывающего кода:

      Процедура ПриИзмененииНоменклатурыСервер(ИдентификаторТекущейСтроки)\n\n // Получаем новую структуру параметров.\n ПараметрыЗаполненияЦен = ЦенообразованиеКлиентСервер.ПараметрыЗаполненияЦеныВСтрокеТЧ(); \n // Заполняем параметры.\n ПараметрыЗаполненияЦен.Дата   = Объект.Дата;\n ПараметрыЗаполненияЦен.Валюта = Объект.Валюта;\n \n ТекущаяСтрока = Объект.Товары.НайтиПоИдентификатору(ИдентификаторТекущейСтроки);\n\n // Передаем структуру параметров в прикладную функцию.\n ЦенообразованиеСервер.ЗаполнитьЦеныВСтрокеТЧ(ТекущаяСтрока, ПараметрыЗаполненияЦен);\n\nКонецПроцедуры\n
      \n

      Пример функции-конструктора параметров в модуле ЦенообразованиеКлиентСервер:

      Функция ПараметрыЗаполненияЦеныВСтрокеТЧ() Экспорт\n \n ПараметрыЗаполненияЦен = Новый Структура;\n ПараметрыЗаполненияЦен.Вставить(\"Дата\");\n ПараметрыЗаполненияЦен.Вставить(\"Валюта\");\n ПараметрыЗаполненияЦен.Вставить(\"ПересчитыватьСумму\", Истина);\n ПараметрыЗаполненияЦен.Вставить(\"ОбязательныеПараметры\",\"Дата,Валюта\"); // обязательные параметры, которые нужно заполнять\n Возврат ПараметрыЗаполненияЦен;\n \nКонецФункции\n
      \n

      Имена свойств структуры соответствуют параметрам вызываемой функции. При этом параметры со значениями по умолчанию должны быть явно проинициализированы в этой структуре.

      \n

      2. В вызывающем коде не следует инициализировать структуру параметров или добавлять в нее какие-либо другие свойства. Во избежание неоднозначности и скрытых ошибок все допустимые параметры вызываемой функции должны быть определены явно в функции-конструкторе параметров.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "1381", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В качестве объекта переадресации из гиперссылки \"См. ...\" указана устаревшая процедура (функция).", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "141", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Необязательные параметры расположены перед обязательными.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "142", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Количество необязательных параметров более 3.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "143", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использование функции \"ТекущаяДата()\".", +"Description": "

      Работа в разных часовых поясах

      #std643

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Конфигурации должны быть рассчитаны на работу в условиях, когда часовой пояс на серверном компьютере не совпадает с реальным часовым поясом пользователей информационной базы. Например, с сервером, расположенным в Москве, работают сотрудники компании из Владивостока, и при этом все операции в системе должны выполняться по местному времени (Владивостока).

      \n

      Такой сценарий работы часто востребован в клиент-серверных информационных базах и в прикладных решениях в модели сервиса (SaaS).

      \n

      2.1. Во всех серверных процедурах и функциях вместо функции ТекущаяДата, которая возвращает дату и время серверного компьютера, следует использовать функцию ТекущаяДатаСеанса, которая приводит время сервера к часовому поясу пользовательского сеанса.

      \n

      2.2. В тех случаях, когда требуется «универсальная» отметка времени, не зависящая от часового пояса текущего сеанса пользователя, в контексте которого выполняется серверный вызов, следует использовать функцию УниверсальноеВремя. Например, для определения момента перезаполнения закешированных данных, для получения времени последнего выполнения фонового задания и т.п.

      \n

      2.3. При использовании методов платформы, возвращающих локальную дату серверного компьютера, следует приводить ее либо к универсальному времени, либо к времени пользовательского сеанса. Например:

      \n

      ДатаАктуальностиУниверсальная = УниверсальноеВремя(ПолнотекстовыйПоиск.ДатаАктуальности());
      ДатаАктуальности = МестноеВремя(ДатаАктуальностиУниверсальная, ЧасовойПоясСеанса());

      \n

      3.1. В клиентском коде использование функции ТекущаяДата также недопустимо. Это требование обусловлено тем, что текущее время, вычисленное в клиентском и серверном коде, не должно различаться.

      \n

      Например, с сервером, расположенным в Москве, работают пользователи из Киева. Функция ТекущаяДата для клиентского компьютера возвращает 10:00, а для сервера – 11:00. В то же время, функция ТекущаяДатаСеанса вернет на сервере 10:00, если в информационной базе установлено киевское время (с помощью метода УстановитьЧасовойПоясИнформационнойБазы).

      \n

      Как правило, вместо вызова функции ТекущаяДата на клиенте необходимо 

      \n
        \n
      • передавать с сервера на клиент время и дату, приведенную к часовому поясу пользовательского сеанса; \n
      • при работе с документами на клиенте, использовать дату документа.
      \n

      Рассмотрим типовые случаи на примерах.

      \n

      3.2. В алгоритме закрытия месяца с клиента на сервер передается дата, по которой далее определяется, какой месяц будет закрываться.

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
       ТекущиеДанные = Элементы.Список.ТекущиеДанные;
       Если ТекущиеДанные = Неопределено Тогда
        ТекДата  = ТекущаяДата();  // вызов ТекущаяДата() на клиенте
       Иначе
        ТекДата  = ТекущиеДанные.Дата;
       КонецЕсли;
       ПараметрыФормы = Новый Структура;
       ПараметрыФормы.Вставить(\"ПериодРегистрации\", ТекДата);
       ОткрытьФорму(\"Обработка.ЗакрытиеМесяца.Форма.Форма\", ПараметрыФормы, ЭтотОбъект);

      \n

      а затем в форме обработки:

      \n

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       ЗаполнитьЗначенияСвойств(Объект, Параметры);
       Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДата());
       КонецЕсли;

      \n

      Правильно

      \n

      перенести получение текущей даты на сервер:

      \n

      &НаКлиенте
      Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
       ТекущиеДанные = Элементы.Список.ТекущиеДанные;
       Если ТекущиеДанные = Неопределено Тогда
        ТекДата  = Неопределено; // нет вызова ТекущаяДата() на клиенте
       Иначе
        ТекДата  = ТекущиеДанные.Дата;
       КонецЕсли;
       ПараметрыФормы = Новый Структура;
       ПараметрыФормы.Вставить(\"ПериодРегистрации\", ТекДата);
       ОткрытьФорму(\"Обработка.ЗакрытиеМесяца.Форма.Форма\", ПараметрыФормы, ЭтотОбъект);

      \n

      и в форме обработки использовать для этого функцию ТекущаяДатаСеанса:

      \n

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       ЗаполнитьЗначенияСвойств(Объект, Параметры);
       Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДатаСеанса());
       КонецЕсли;

      \n

      3.3. При работе с документами следует рассмотреть возможность использования даты самого документа вместо текущей даты. Например, в реализации подбора номенклатуры в табличную часть документа, в форму подбора из клиентского кода передается дата расчетов для вывода цен и остатков на эту дату.

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура ПодборТовары(Команда)
       ПараметрыПодбора = Новый Структура;
       ДатаРасчетов = ?(НачалоДня(Объект.Дата) = НачалоДня(ТекущаяДата()),
        Неопределено, Объект.Дата); // вызов ТекущаяДата() на клиенте
       ПараметрыПодбора.Вставить(\"ДатаРасчетов\", ДатаРасчетов);
       ...
       ОткрытьФорму(\"Обработка.ПодборНоменклатуры.Форма.Форма\", ПараметрыПодбора,
        ЭтотОбъект, УникальныйИдентификатор);

      \n

      Правильно

      \n

      передавать на сервер дату документа, а вычисление даты расчетов выполнять на сервере:

      \n

      &НаКлиенте
      Процедура ПодборТовары(Команда)
       ПараметрыПодбора = Новый Структура;
       ПараметрыПодбора.Вставить(\"ДатаРасчетов\", Объект.Дата);
       ...
       ОткрытьФорму(\"Обработка.ПодборНоменклатуры.Форма.Форма\", ПараметрыПодбора,
        ЭтотОбъект, УникальныйИдентификатор);

      \n

      Другой пример. При подборе документов для зачета аванса в форме подбора устанавливается отбор по условию «дата документов аванса не больше переданной в форму».

      \n

      Неправильно:

      \n

      &НаКлиенте
      Процедура ЗачетАвансовДокументАвансаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
       СтандартнаяОбработка = Ложь;
       ПараметрыФормы = Новый Структура;
        ПараметрыФормы.Вставить(\"КонецПериода\",                                   
      ?(ЗначениеЗаполнено(Параметры.Ключ), Объект.Дата - 1, КонецДня(ТекущаяДата()))); // вызов ТекущаяДата() на клиенте
       ...
        ОткрытьФорму(\"Документ.ДокументРасчетовСКонтрагентом.ФормаВыбора\",        
      ПараметрыФормы, Элемент);
      ...

      \n

      Правильно

      \n

      вычислять параметр КонецПериода по дате документа:

      \n

      &НаКлиенте
      Процедура ЗачетАвансовДокументАвансаНачалоВыбора(Элемент, ДанныеВыбора,
      СтандартнаяОбработка)
       СтандартнаяОбработка = Ложь;
       ПараметрыФормы = Новый Структура;
        ПараметрыФормы.Вставить(\"КонецПериода\", ?(ЗначениеЗаполнено(Параметры.Ключ),
        Объект.Дата - 1, КонецДня(Объект.Дата)));
       ...
        ОткрытьФорму(\"Документ.ДокументРасчетовСКонтрагентом.ФормаВыбора\", ПараметрыФормы, Элемент);

      \n

      3.4. В остальных случаях при использовании Библиотеки стандартных подсистем рекомендуется использовать функцию ДатаСеанса общего модуля ОбщегоНазначенияКлиент.

      \n

      4. Исключения из правил 2 и 3 возможны в отдельных, обоснованных случаях, когда требуется использовать действительно текущее время серверного компьютера. Такие исключения должны быть обоснованы в тексте комментария к вызову.

      \n

      5. Следует избегать в коде одной процедуры (функции) многократного обращения к функции ТекущаяДатаСеанса (ТекущаяДата), так как возвращаемые значения будут отличаться друг от друга.

      \n

      Неправильно

      \n

      ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
      ДатаСледующегоОповещения = РассчитатьДату() + ТекущаяДатаСеанса();

      \n

      Правильно

      \n

      использовать ранее рассчитанные дату и время:

      \n

      ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
      ДатаСледующегоОповещения = РассчитатьДату() + ДатаПоследнегоОповещения;

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "144", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Присвоение параметру \"Отказ\" значения, отличного от \"Истина\".", +"Description": "

      Работа с параметром «Отказ» в обработчиках событий

      #std686

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В обработчиках событий модулей объектов, наборов записей, форм и т.п., содержащих параметр Отказ (ПриЗаписи, ОбработкаПроверкиЗаполнения, ТоварыПередНачаломДобавления и т.п.), не следует присваивать этому параметру значение Ложь.
      Это требование обусловлено тем, что, как правило, в коде обработчиков событий параметр Отказ может устанавливаться сразу в нескольких последовательных проверках (или в нескольких подписках на одно и то же событие). В таком случае к моменту выполнения очередной проверки параметр Отказ уже может заранее содержать значение Истина, и можно ошибочно сбросить его обратно в Ложь.
      Кроме того, при доработках конфигурации на внедрении число этих проверок может увеличиться.

      \n

      Неправильно:

      Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)\n  ...\n  Отказ = ЕстьОшибкиЗаполнения();\n  ...\nКонецПроцедуры
      \n

      Правильно:

      Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)\n  ...\n  Если ЕстьОшибкиЗаполнения() Тогда\n   Отказ = Истина;\n  КонецЕсли;\n  ...\nКонецПроцедуры\n
      \n

      или

      Отказ = Отказ Или ЕстьОшибкиЗаполнения();\n
      \n

      2. Эти же требования справедливы для других аналогичных параметров обработчиков событий: СтандартнаяОбработка, Выполнение и др.
      Например:

      Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)\n \n  Если Параметры.Свойства(...) Тогда\n    СтандартнаяОбработка = Ложь;\n    ...
      \n КонецЕсли;\n\nКонецПроцедуры\n
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "145", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Выключен флаг \"Устанавливать права для новых объектов\" или \"Устанавливать права для реквизитов и табличных частей по умолчанию\" у роли \"Полные права\".", +"Description": "\n

      Установка прав для новых объектов и полей объектов

      #std532

      Область применения: управляемое приложение, обычное приложение.

      \n

      При разработке ролей конфигурации следует придерживаться такой методики установки прав на объекты метаданных, которая не допускает появления в конфигурации ролей, дающих доступ к полям объекта, но не к самому объекту; и как следствие, позволяет избежать потенциальные проблемы настройки прав доступа на внедрении, когда пользователь может ошибочно получить доступ ко всем реквизитам объекта метаданных при назначении ему подобной роли.

      \n
        \n
      1. \n
        Флажок «Устанавливать права для новых объектов» должен быть установлен только у роли ПолныеПрава
        \n
      2. \n
        При добавлении новой роли, флажок «Устанавливать права для реквизитов и табличных частей по умолчанию» должен быть установлен, а флажок «Независимые права подчиненных объектов» должен быть снят.
        \n
      3. \n
        При необходимости установить в роли права только на поля какого-либо объекта метаданных (права просмотр, редактирование на реквизиты, табличные части, измерения, команды и т.п. без этих прав на сам объект), предварительно требуется следующее. В роли установить флажок «Независимые права подчиненных объектов», а флажок «Устанавливать права для реквизитов и табличных частей по умолчанию» снять с очисткой прав на все реквизиты и табличные части.
        \n
      4. \n
        При добавлении в конфигурацию новых объектов или новых полей существующих объектов следует настроить права на эти объекты или поля в соответствующих ролях.
      \n

      Пример настройки прав в роли ДобавлениеИзменениеВидовКонтактнойИнформации:

      \n


      \n

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "146", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Флаг \"Устанавливать права для новых объектов\" должен быть включен только у роли \"ПолныеПрава\".", +"Description": "\n

      Установка прав для новых объектов и полей объектов

      #std532

      Область применения: управляемое приложение, обычное приложение.

      \n

      При разработке ролей конфигурации следует придерживаться такой методики установки прав на объекты метаданных, которая не допускает появления в конфигурации ролей, дающих доступ к полям объекта, но не к самому объекту; и как следствие, позволяет избежать потенциальные проблемы настройки прав доступа на внедрении, когда пользователь может ошибочно получить доступ ко всем реквизитам объекта метаданных при назначении ему подобной роли.

      \n
        \n
      1. \n
        Флажок «Устанавливать права для новых объектов» должен быть установлен только у роли ПолныеПрава
        \n
      2. \n
        При добавлении новой роли, флажок «Устанавливать права для реквизитов и табличных частей по умолчанию» должен быть установлен, а флажок «Независимые права подчиненных объектов» должен быть снят.
        \n
      3. \n
        При необходимости установить в роли права только на поля какого-либо объекта метаданных (права просмотр, редактирование на реквизиты, табличные части, измерения, команды и т.п. без этих прав на сам объект), предварительно требуется следующее. В роли установить флажок «Независимые права подчиненных объектов», а флажок «Устанавливать права для реквизитов и табличных частей по умолчанию» снять с очисткой прав на все реквизиты и табличные части.
        \n
      4. \n
        При добавлении в конфигурацию новых объектов или новых полей существующих объектов следует настроить права на эти объекты или поля в соответствующих ролях.
      \n

      Пример настройки прав в роли ДобавлениеИзменениеВидовКонтактнойИнформации:

      \n


      \n

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "148", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Реквизит \"Ссылка\" динамического списка не выведен в таблицу на форме.", +"Description": "

      Реквизит Ссылка и признак \"Использовать всегда\" в динамических списках

      #std702

      Область применения: управляемое приложение.

      \n

      Рекомендация (полезный совет)

      \n

      1. Используя возможности управляемых форм, пользователь может добавить отображение любых реквизитов объектов в динамическом списке. Для того чтобы пользователь смог воспользоваться этой возможностью, рекомендуется добавлять в список поле Ссылка, у которого нужно отключать пользовательскую видимость.

      \n

      Кроме того, при использовании в объектах различных механизмов платформы 1С:Предприятие и Библиотеку стандартных подсистем) наличие реквизита Ссылка в динамических списках может быть критичным для работоспособности этих механизмов. Например:

      \n
        \n
      • при использовании механизма характеристик платформы 1С:Предприятие (или подсистемы \"Свойства\" Библиотеки стандартных подсистем) в динамические списки рекомендуется всегда выводить реквизит Ссылка, т.к. характеристики (дополнительные реквизиты и сведения) можно вывести в колонки списка только используя настройку в пользовательском режиме; \n
      • при разработке команд печати (подсистема \"Печать\" Библиотеки стандартных подсистем) реквизит Ссылка с признаком \"Использовать всегда\" становится обязательным для корректной работы этих команд.
      \n

      2.1. При обращении к данным строки динамического списка в коде (например, в обработчике ПриАктивацииСтроки, ПриПолученииДанныхНаСервере и др.) необходимо учитывать, что в целях оптимизации данные невидимых колонок не получаются. При этом видимостью может управлять, в том числе, пользователь.

      \n

      2.2. Для колонок, у которых в свойствах таблицы формы, отображающей динамический список установлен признак \"Использовать всегда\" данные получаются всегда, вне зависимости от видимости.
      Не рекомендуется устанавливать признак \"Использовать всегда\" для колонки реквизита динамического списка, кроме тех случаев, когда значение колонки обязательно для выполнения алгоритма. Например, колонка Ссылка всегда требуется для команды \"Печать\",  но эта колонка может быть скрыта пользователем.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "149", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "У поля \"Ссылка\" таблицы динамического списка не отключена пользовательская видимость.", +"Description": "

      Реквизит Ссылка и признак \"Использовать всегда\" в динамических списках

      #std702

      Область применения: управляемое приложение.

      \n

      Рекомендация (полезный совет)

      \n

      1. Используя возможности управляемых форм, пользователь может добавить отображение любых реквизитов объектов в динамическом списке. Для того чтобы пользователь смог воспользоваться этой возможностью, рекомендуется добавлять в список поле Ссылка, у которого нужно отключать пользовательскую видимость.

      \n

      Кроме того, при использовании в объектах различных механизмов платформы 1С:Предприятие и Библиотеку стандартных подсистем) наличие реквизита Ссылка в динамических списках может быть критичным для работоспособности этих механизмов. Например:

      \n
        \n
      • при использовании механизма характеристик платформы 1С:Предприятие (или подсистемы \"Свойства\" Библиотеки стандартных подсистем) в динамические списки рекомендуется всегда выводить реквизит Ссылка, т.к. характеристики (дополнительные реквизиты и сведения) можно вывести в колонки списка только используя настройку в пользовательском режиме; \n
      • при разработке команд печати (подсистема \"Печать\" Библиотеки стандартных подсистем) реквизит Ссылка с признаком \"Использовать всегда\" становится обязательным для корректной работы этих команд.
      \n

      2.1. При обращении к данным строки динамического списка в коде (например, в обработчике ПриАктивацииСтроки, ПриПолученииДанныхНаСервере и др.) необходимо учитывать, что в целях оптимизации данные невидимых колонок не получаются. При этом видимостью может управлять, в том числе, пользователь.

      \n

      2.2. Для колонок, у которых в свойствах таблицы формы, отображающей динамический список установлен признак \"Использовать всегда\" данные получаются всегда, вне зависимости от видимости.
      Не рекомендуется устанавливать признак \"Использовать всегда\" для колонки реквизита динамического списка, кроме тех случаев, когда значение колонки обязательно для выполнения алгоритма. Например, колонка Ссылка всегда требуется для команды \"Печать\",  но эта колонка может быть скрыта пользователем.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "150", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована неправильная конструкция при установке внешней компоненты.", +"Description": "

      Установка внешних компонент и расширений платформы

      #std700

      Область применения: управляемое приложение.

      \n

      1.1. Установка внешних компонент и расширений платформы должна быть интерактивной. Пользователь должен самостоятельно принять решение об установке. В диалоге установки должно быть указано, для чего нужна компонента (расширение) и что не будет работать, если ее не устанавливать.

      \n

      Например, неправильно использовать конструкции вида

      \n

      Если Не ПодключитьВнешнююКомпоненту(…) Тогда
        УстановитьВнешнююКомпоненту(…)

      \n

      Правильно задавать пользователю вопрос в явном виде:

      \n
      \n

      Для продолжения работы требуется установить внешнюю компоненту, которая позволит работать с отчетностью. Для установки компоненты нажмите \"Установить\". После завершения установки нажмите \"Продолжить\".

      \n

      1.2. Рекомендуется выводить предложение об установки компоненты (расширения) перед выполнениям прикладного действия.
      Например:

      \n
        \n
      • Пользователь воспользовался командой «Отправить отчет» \n
      • Для этого конфигурации необходимо, чтобы была установлена какая-либо внешняя компонента. \n
      • Конфигурация проверяет, установлена ли компонента. \n
      • Если компонента не установлена, отображает пользователю информацию о том, что для отправки отчета нужно установить компоненту и кнопку, вызывающую установку компоненты. \n
      • Пользователь нажимает на кнопку, выполняется установка. \n
      • После установки пользователь нажимает на кнопку «Продолжить отправку отчета» \n
      • Программа продолжает отправлять отчет.
      \n

      Такой сценарий позволит обеспечить, чтобы компоненты (расширения) устанавливались без проблем на всех поддерживаемых браузерах, в том числе, в браузере FireFox.

      \n

      Другой пример. Предложение об установке расширения работы с файлами при загрузке файла из файловой системы:

      \n

      \n

      1.3. При использовании в конфигурации Библиотеки стандартных подсистем для вывода предложения об установке расширения работы с файлами следует использовать следующие процедуры общего модуля ФайловаяСистемаКлиент в следующих сценариях:

      \n
        \n
      • ВыбратьКаталог вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы ВыборКаталога; \n
      • ЗагрузитьФайл вместо методов глобального контекста ПоместитьФайл, НачатьПомещениеФайла, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Открытие; \n
      • ЗагрузитьФайлы вместо методов глобального контекста ПоместитьФайлы, НачатьПомещениеФайлов, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Открытие; \n
      • ОткрытьФайл вместо метода глобального контекста ЗапуститьПриложение для открытия файла, ассоциированного с некоторым приложением; \n
      • СохранитьФайл вместо метода глобального контекста ПолучитьФайл или метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Сохранение; \n
      • СохранитьФайлы вместо методов глобального контекста ПолучитьФайлы, НачатьПолучениеФайлов, а также вместо метода Показать объекта ДиалогВыбораФайла с заданным режимом работы Сохранение. \n
      • В остальных случаях, для вывода предложения об установке расширения работы с файлами следует использовать процедуру ПодключитьРасширениеДляРаботыСФайлами.

        \n
      \n


      2. В прикладном решении должны быть предоставлены инструменты для установки пользователем внешних компонент и расширений в любой момент работы. Таким образом, их можно установить не только в ходе решения какой-то задачи, но и в виде отдельного действия (из некоторого административного режима).

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем для установки расширения для работы с файлами предназначена общая команда УстановитьРасширениеРаботыСФайлами, которую рекомендуется размещать в форме персональных настроек пользователя (см. общую форму _ДемоМоиНастройки в демонстрационной конфигурации). В этой же форме рекомендуется размещать команды по установке внешних компонент, которые могут потребоваться пользователю при его работе.

      \n

      См. также

      \n\n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "152", +"Type": "BUG", +"Severity": "MINOR", +"Name": "В параметре \"ИмяСобытия\" метода \"ЗаписьЖурналаРегистрации()\" имеется лишний пробел после точки.", +"Description": "

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      \n\n\n

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "153", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Не локализован параметр \"Комментарий\" метода \"ЗаписьЖурналаРегистрации()\".", +"Description": "

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n\n\n\n

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "154", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Если в параметре \"Комментарий\" метода \"ЗаписьЖурналаРегистрации()\" указано подробное описание ошибки, то уровень журнала должен быть \"Ошибка\".", +"Description": "

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      \n\n\n

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "156", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Не локализован параметр \"ИмяСобытия\" метода \"ЗаписьЖурналаРегистрации()\".", +"Description": "

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n\n\n\n

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "157", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Для параметра \"ИмяСобытия\" метода \"ЗаписьЖурналаРегистрации()\" не задан основной язык конфигурации.", +"Description": "

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      \n\n\n

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "160", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "У реквизита \"Ссылка\" динамического списка выключен признак \"Использовать всегда\".", +"Description": "

      Реквизит Ссылка и признак \"Использовать всегда\" в динамических списках

      #std702

      Область применения: управляемое приложение.

      \n

      Рекомендация (полезный совет)

      \n

      1. Используя возможности управляемых форм, пользователь может добавить отображение любых реквизитов объектов в динамическом списке. Для того чтобы пользователь смог воспользоваться этой возможностью, рекомендуется добавлять в список поле Ссылка, у которого нужно отключать пользовательскую видимость.

      \n

      Кроме того, при использовании в объектах различных механизмов платформы 1С:Предприятие и Библиотеку стандартных подсистем) наличие реквизита Ссылка в динамических списках может быть критичным для работоспособности этих механизмов. Например:

      \n
        \n
      • при использовании механизма характеристик платформы 1С:Предприятие (или подсистемы \"Свойства\" Библиотеки стандартных подсистем) в динамические списки рекомендуется всегда выводить реквизит Ссылка, т.к. характеристики (дополнительные реквизиты и сведения) можно вывести в колонки списка только используя настройку в пользовательском режиме; \n
      • при разработке команд печати (подсистема \"Печать\" Библиотеки стандартных подсистем) реквизит Ссылка с признаком \"Использовать всегда\" становится обязательным для корректной работы этих команд.
      \n

      2.1. При обращении к данным строки динамического списка в коде (например, в обработчике ПриАктивацииСтроки, ПриПолученииДанныхНаСервере и др.) необходимо учитывать, что в целях оптимизации данные невидимых колонок не получаются. При этом видимостью может управлять, в том числе, пользователь.

      \n

      2.2. Для колонок, у которых в свойствах таблицы формы, отображающей динамический список установлен признак \"Использовать всегда\" данные получаются всегда, вне зависимости от видимости.
      Не рекомендуется устанавливать признак \"Использовать всегда\" для колонки реквизита динамического списка, кроме тех случаев, когда значение колонки обязательно для выполнения алгоритма. Например, колонка Ссылка всегда требуется для команды \"Печать\",  но эта колонка может быть скрыта пользователем.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "161", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Параметр \"ИмяСобытия\" метода \"ЗаписьЖурналаРегистрации()\" инициализируется функцией, возращающей нелокализованную строку.", +"Description": "

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n\n\n\n

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "162", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не установлено право.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "163", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Строка текста модуля содержит букву \"ё\".", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 5 +}, +{ +"Code": "164", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Установлено право \"Удаление\".", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "165", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлено лишнее право.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "192", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлено право \"ИнтерактивноеУдалениеПредопределенныхДанных\".", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n\n\n\n

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "193", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Установлено право \"ИнтерактивнаяПометкаУдаленияПредопределенныхДанных\".", +"Description": "

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n\n\n\n

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "194", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Установлено право \"ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных\".", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n\n\n\n

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "195", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Установлено право \"ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных\".", +"Description": "

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n\n\n\n

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "216", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Слово содержит кириллицу и латиницу.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "217", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неправильная кодировка символа \"минус\".", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "218", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлены все права в роли \"ПолныеПрава\" для объекта, не входящего в состав разделителя.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "219", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Установлены все права в роли \"АдминистраторСистемы\" для объекта, входящего в состав разделителя.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "220", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не установлено право в роли \"АдминистраторСистемы\".", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "222", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использование устаревшей процедуры.", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "223", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использование устаревшей функции.", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "224", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Для обязательной роли установлен неправильный синоним.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "226", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В документе, предполагающем проведение, не установлен флаг \"Привилегированный режим при проведении\".", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "227", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В документе, предполагающем проведение, не установлен флаг \"Привилегированный режим при отмене проведения\".", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "228", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В функциональной опции не установлен флаг \"Привилегированный режим при получении\".", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "229", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В роли есть право на изменение регистра, подчиненного регистратору.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "230", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Роль не включена ни в одну подсистему.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "232", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно установлены права на константу.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "233", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Для подсистемы верхнего уровня, отображаемой в командном интерфейсе, не найдено роли.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "234", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В роли не установлено право просмотра для подсистемы.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "235", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в имени элемента формы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "236", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Неверно образован синоним объекта с префиксом \"Удалить\".", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "239", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "В модуле должны быть определены стандартные области.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "240", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Код в модуле с (возможным) программным интерфейсом размещен вне стандартных областей.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "241", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Код размещен вне стандартных областей.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "242", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не установлен признак переключения для интерфейса.", +"Description": "

      Общие интерфейсы

      #std501

      Область применения: обычное приложение.

      \n

      Обычное приложение

      \n

      1. Для отображения общих для всех переключаемых прикладных интерфейсов пунктов меню и панелей инструментов в конфигурации создается интерфейс Общий. У него снимается признак Переключаемый, а в качестве подсистемы указывается вся конфигурация.

      \n

      2. На верхнем уровне главного меню должны обязательно располагаться в крайней левой позиции подменю Файл и в крайней правой позиции набор подменю Сервис, Окна, Справка.

      \n

      3. В меню Сервис может присутствовать подменю Переключить интерфейс для переключения текущего интерфейса на другой. Подменю должно содержать список всех переключаемых интерфейсов конфигурации.

      \n

      4. В интерфейсе Общий рекомендуется отключать подменю Операции, кроме случаев, когда это подменю используется во всех переключаемых интерфейсах конфигурации.

      \n

      5. В конфигурации может быть создано несколько непереключаемых интерфейсов для того, чтобы реализовать зависимость состава главного меню и панелей инструментов от роли пользователя. Для этого состав интерфейсов конфигурации дополняется интерфейсами, названия которых начинаются со слова Общий…. Для таких интерфейсов снимается признак Переключаемый и право на их использование дается тем или иным ролям.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "244", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Длинные комментарии должны начинаться с большой буквы.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "246", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Нет пробела в начале комментария.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "247", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Имена переменных не должны состоять из одного символа.", +"Description": "

      Правила образования имен переменных

      #std454

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Имена переменных следует образовывать от терминов предметной области таким образом, чтобы из имени переменной было понятно ее назначение.

      2. Имена следует образовывать путем удаления пробелов между словами. При этом, каждое слово в имени пишется с прописной буквы. Предлоги и местоимения из одной буквы также пишутся прописными буквами.
      Пример:

      Перем ДиалогРаботыСКаталогом; // Диалог работы с каталогом \nПерем КоличествоПачекВКоробке; // Количество пачек в коробке\n
      \n

      Примеры некорректных имен переменных:

      масРеквизитов, соотвВидИмя, новСтр\n
      \n

      3. Имена переменных запрещается начинать с подчеркивания.

      \n

      4. Имена переменных не должны состоять из одного символа. Использование односимвольных имен переменных допускается только для счетчиков циклов.

      5. Переменные, отражающие состояние некоторого флага, следует называть так, как пишется истинное значение этого флага.
      Например:

      Перем ЕстьОшибки; // Признак наличия ошибок в процедуре. \nПерем ЭтоТоварТара; // Признак, что товар относится к возвратной таре. \n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "248", +"Type": "CODE_SMELL", +"Severity": "MAJOR", +"Name": "Имена переменных не должны начинаться с подчеркивания.", +"Description": "

      Правила образования имен переменных

      #std454

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Имена переменных следует образовывать от терминов предметной области таким образом, чтобы из имени переменной было понятно ее назначение.

      2. Имена следует образовывать путем удаления пробелов между словами. При этом, каждое слово в имени пишется с прописной буквы. Предлоги и местоимения из одной буквы также пишутся прописными буквами.
      Пример:

      Перем ДиалогРаботыСКаталогом; // Диалог работы с каталогом \nПерем КоличествоПачекВКоробке; // Количество пачек в коробке\n
      \n

      Примеры некорректных имен переменных:

      масРеквизитов, соотвВидИмя, новСтр\n
      \n

      3. Имена переменных запрещается начинать с подчеркивания.

      \n

      4. Имена переменных не должны состоять из одного символа. Использование односимвольных имен переменных допускается только для счетчиков циклов.

      5. Переменные, отражающие состояние некоторого флага, следует называть так, как пишется истинное значение этого флага.
      Например:

      Перем ЕстьОшибки; // Признак наличия ошибок в процедуре. \nПерем ЭтоТоварТара; // Признак, что товар относится к возвратной таре. \n
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "249", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Оператор \"Перейти\" не поддерживается платформой \"1С:Предприятие\" в режиме веб-клиента.", +"Description": "

      Ограничение на использование оператора Перейти

      #std547

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      1. В коде на встроенном языке не рекомендуется использовать оператор Перейти, так как необдуманное использование данного оператора приводит к получению запутанных, плохо структурированных модулей, по тексту которых затруднительно понять порядок исполнения и взаимозависимость фрагментов. Вместо оператора Перейти рекомендуется использовать другие конструкции встроенного языка. 

      \n

      Например, неправильно:

      \n

       Если ПланВидовРасчета = Объект.ПланВидовРасчета Тогда
        
        Перейти ~ПланВидовРасчета;
        
       КонецЕсли;

      \n

      правильно

      \n

       Если ПланВидовРасчета = Объект.ПланВидовРасчета Тогда
        
        ОбработатьПланВидовРасчета();
        
       КонецЕсли;

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      2. Запрещается использовать оператор Перейти в общих модулях с признаком \"Клиент (управляемое приложение)\", модулях команд и в клиентском коде модулей управляемых форм, так как данный метод не поддерживается платформой 1С:Предприятие в режиме веб-клиента.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "250", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Найдена экспортная процедура или функция в модуле команды.", +"Description": "

      Ограничения на использование экспортных процедур и функций

      #std544

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Не следует размещать экспортные процедуры и функции в модулях команд и общих команд. К этим модулям нет возможности обращаться из внешнего по отношению к ним кода, поэтому экспортные процедуры и функции в этих модулях не имеют смысла.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "251", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обязательная роль не установлена как основная роль конфигурации.", +"Description": "

      Стандартные роли

      #std488

      Область применения: управляемое приложение, обычное приложение.

      \n

      1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

      \n

      1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

      \n

      Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

      \n

      2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
      ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

      \n

      2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • позволять самостоятельное использование (может быть назначена пользователям); \n
      • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
      • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
      • включать в себя перечисленные права: \n
          \n
        • Администрирование данных \n
        • Активные пользователи \n
        • Журнал регистрации \n
        • Монопольный режим \n
        • Тонкий клиент \n
        • Веб-клиент \n
        • Сохранение данных пользователя \n
        • Вывод
      \n

      В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

      \n

      При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

      \n

      2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
      Эта роль должна:

      \n
        \n
      • \n
        \n
        назначаться пользователям только совместно с ролью ПолныеПрава;
        \n
      • \n
        \n
        предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
        \n
      • \n
        содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
        \n
      • \n
        включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
      Эта роль должна:

      \n
        \n
      • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
      \n

      При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

      \n

      При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

      \n

      2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

      \n

      Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

      \n

      3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

      \n

      3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

      \n

      3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

      \n

      3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

      \n

      3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

      \n

      3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

      \n

      3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

      \n

      3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

      \n

      3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

      \n

      3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

      \n

      3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

      \n

      3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

      \n

      Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

      \n
        \n
      • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
      • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
      • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
      \n

      то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

      \n
      \n

      См. также: Работа с пользовательскими настройками

      \n

      4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

      \n

      4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
      Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

      \n

      4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

      \n

      При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

      \n

      5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

      \n
        \n
      • Право интерактивного удаления \n
      • Интерактивное удаление предопределенных данных \n
      • Интерактивная пометка удаления предопределенных данных \n
      • Интерактивное снятие пометки удаления предопределенных данных \n
      • Интерактивное удаление помеченных предопределенных данных
      \n

      Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "254", +"Type": "CODE_SMELL", +"Severity": "MINOR", +"Name": "Ключевое слово запроса написано не канонически.", +"Description": "

      Оформление текстов запросов

      #std437

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Все ключевые слова языка запросов пишутся заглавными буквами.

      \n

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Рекомендуется указывать и необязательные конструкции запроса, прежде всего - явно назначать псевдонимы полям, в целях повышения наглядности текста запроса и \"устойчивости\" использующего его кода. Например, если в алгоритме используется запрос с полем, объявленным как

      \n

      Касса.Валюта

      \n

      при изменении имени реквизита нужно будет также изменить и код, осуществляющий обращение по имени свойства Валюта к выборке из результата запроса. Если же поле будет объявлено как

      \n

      Касса.Валюта КАК Валюта

      \n

      то изменение имени реквизита приведет только к изменению текста запроса.

      \n
      \n

      2а. Особенно внимательно следует относиться к автоматически присваиваемым псевдонимам для полей – реквизитов других полей, типа \"... Касса.Валюта.Наименование...\". В приведенном выше примере поле получит автоматический псевдоним ВалютаНаименование, а не Наименование.

      \n

      2б. Следует обязательно указывать ключевое слово КАК перед псевдонимом поля источника.

      \n

      3. Текст запроса должен быть структурирован, не следует писать запрос в одну строку, даже короткий. Текст запроса должен быть нагляден, поскольку это существенно улучшает его понимание другими разработчиками.

      4. В запросы, сложные для понимания, в которых используются вложенные запросы, объединения или соединения рекомендуется вставлять комментарии. Комментарии, например, могут объяснять для получения каких данных используется та или иная таблица в соединении или объединении.

      \n

      При этом необходимо иметь в виду, что при использовании конструктора запросов, все комментарии в запросе удаляются автоматически без предупреждения.

      5. При создании объекта Запрос рекомендуется указывать комментарии, для получения какой информации или каких иных целей будет использован данный запрос.

      6.1 При программной \"сборке\" текста запроса рекомендуется комментировать все этапы его сборки.

      \n

      6.2. Нужно стараться, чтобы каждая часть формируемого запроса могла быть открыта с помощью конструктора запросов

      \n
        \n
      • это позволяет осуществить экспресс-проверку корректности синтаксиса запроса \n
      • это упрощает разработку и сопровождение кода конфигурации, в том числе сторонними разработчиками
      \n

      Типичные случаи программной модификации текста запроса

      \n

      Изменение имени поля выборки или таблицы

      \n

      Неправильно

      \n

      ТекстЗапроса =

      \n

      \"ВЫБРАТЬ
      | Номенклатура.Наименование  КАК Наименование ,
      | Номенклатура. \" + ИмяПоляКод + \" КАК КодАртикул
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура\";

      \n


      Правильно

      \n

      ТекстЗапроса =
      \"ВЫБРАТЬ
      | Номенклатура.Наименование  КАК Наименование,
      | &ИмяПоляКод  КАК КодАртикул
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура ;

      \n

      ТекстЗапроса = СтрЗаменить(ТекстЗапроса , \"&ИмяПоляКод \", \"Номенклатура.\" + ИмяПоляКод);

      \n

      или аналогично для имени таблицы

      \n

      ТекстЗапроса =

      \n

      \"ВЫБРАТЬ
      | ТаблицаСправочника.Наименование  КАК Наименование,
      | ТаблицаСправочника.Код  КАК Код
      |ИЗ
      | &ТаблицаСправочника КАК ТаблицаСправочника\";
      ТекстЗапроса = СтрЗаменить(ТекстЗапроса , \"&ТаблицаСправочника\", \"Справочник.\" + ИмяСправочника);

      \n

      или еще один вариант для имени таблицы

      \n

      ТекстЗапроса =

      \n

      \"ВЫБРАТЬ
      | Номенклатура.Наименование  КАК НаименованиеТовара ,
      | ЕСТЬNULL(ТаблицаОстатков.ВНаличииОстаток,0) КАК ОстатокТовара
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура
      | ЛЕВОЕ СОЕДИНЕНИЕ #ТаблицаОстатков КАК ТаблицаОстатков
      | ПО Номенклатура.Ссылка= ТаблицаОстатков.Номенклатура\";

      Если ИспользуетсяАдресноеХранение Тогда
       ТекстЗапроса = СтрЗаменить(ТекстЗапроса , \"#ТаблицаОстатков\", \"РегистрНакопления.ТоварыВЯчейках.Остатки\");
      Иначе
       ТекстЗапроса = СтрЗаменить(ТекстЗапроса , \"#ТаблицаОстатков\", \"РегистрНакопления.ТоварыНаСкладах.Остатки\");
      КонецЕсли;

      \n

      Конкатенация нескольких текстов запросов в пакет

      \n

      Неправильно

      \n

      ТекстЗапроса = \" \";

      \n

      Если ИспользоватьУпаковки Тогда

      \n

      ТекстЗапроса =

      \n

      \"ВЫБРАТЬ
      | Упаковки.Ссылка КАК Ссылка
      |ИЗ
      | Справочник.Упаковки КАК Упаковки;
      |/////////////////////////////////////////////////////////////
      |\";

      \n

      КонецЕсли;

      \n

      ТекстЗапроса = ТекстЗапроса +
      \"ВЫБРАТЬ
      | Номенклатура.Ссылка КАК Ссылка
      |ИЗ
      | Справочник. Номенклатура КАК Номенклатура\";

      \n

      Правильно

      \n

      ТекстЗапроса = \" \";

      \n

      Если ИспользоватьУпаковки Тогда

      \n

      ТекстЗапроса =

      \n

      \"ВЫБРАТЬ
      | Упаковки.Ссылка КАК Ссылка
      |ИЗ
      | Справочник.Упаковки КАК Упаковки\";

      \n

      ТекстЗапроса = ТекстЗапроса +
      \"
      |;
      |/////////////////////////////////////////////////////////////
      |\";

      \n

      КонецЕсли;

      \n

      ТекстЗапроса = ТекстЗапроса +
      \"ВЫБРАТЬ
      | Номенклатура.Ссылка КАК Ссылка
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура\";

      \n

      Или

      \n

      Разделитель =
      \"
      |;
      |/////////////////////////////////////////////////////////////
      |\";

      \n

      ТекстыЗапросовПакета = Новый Массив;

      \n

      ТекстЗапроса =
      \"ВЫБРАТЬ
      | Упаковки.Ссылка КАК Ссылка
      |ИЗ
      | Справочник.Упаковки КАК Упаковки\";

      \n

      ТекстыЗапросовПакета.Добавить(ТекстЗапроса);

      \n

      ТекстЗапроса =
      \"ВЫБРАТЬ
      | Номенклатура.Ссылка КАК Ссылка
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура \";

      \n

      ТекстыЗапросовПакета.Добавить(ТекстЗапроса);
      ТекстЗапроса = СтрСоединить(ТекстыЗапросовПакета, Разделитель);

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "256", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В объекте \"Подписка на событие\" использован обработчик из общего модуля, не являющегося клиент-серверным.", +"Description": "

      Поддержка толстого клиента, управляемое приложение, клиент-сервер

      #std680

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В управляемом режиме из-за ряда ограничений тонкого клиента может возникнуть необходимость поддержки запуска толстого клиента (в режиме управляемого приложения). Подробнее см. Функциональность обычного приложения, отсутствующая в управляемом приложении.

      \n

      2. При этом разработка конфигураций, рассчитанных на режим управляемого приложения, как правило, ведется исходя из того, что в клиент-серверной архитектуре код следующих модулей компилируется и выполняется только на сервере

      \n
        \n
      • модуль менеджера; \n
      • модуль объекта; \n
      • модуль сеанса.
      \n

      В частности, в указанных модулях может встречаться обращение к общим модулям, доступным только на сервере.

      \n

      Однако в толстом клиенте, в режиме управляемого приложения, клиент-сервер, возможны ситуации, когда указанные модули могут начать компилироваться и выполняться на стороне клиента, в частности:

      \n
        \n
      • если объект (справочник, документ и т.п.) явно создается и вызывается в клиентском коде; \n
      • когда платформа 1С:Предприятие неявно обращается к модулям менеджеров и модулю сеанса для вызова их обработчиков событий на клиенте.
      \n

      Компиляция и выполнение таких модулей на клиенте могут приводить к ошибкам. По этой причине режим проверки конфигурации для режима толстый клиент, управляемое приложение, может находить ошибки в указанных модулях.

      \n

      Для того чтобы избежать незапланированной компиляции и исполнения указанных модулей на клиенте, а также чтобы избежать лишних сообщений режима проверки конфигурации, следует:

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей объектов (наборов записей и т.п.), заключив его в инструкцию препроцессора и дополнив вызовом исключения, которое предотвращает несанкционированную попытку использования объекта на клиенте:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #Иначе
        ВызватьИсключение НСтр(\"ru = 'Недопустимый вызов объекта на клиенте.'\");
      #КонецЕсли

      \n
        \n
      • полностью исключить из клиентского контекста код модуля сеанса, заключив его в инструкцию препроцессора (так как параметры сеанса требуются для работы серверного, а не клиентского кода конфигурации):
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #КонецЕсли

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей менеджеров всех видов объектов метаданных, заключив его в инструкцию препроцессора:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

      #КонецЕсли

      \n

      В последнем случае также будет действовать следующее ограничение: если представление объектов формируется обработчиками событий модуля менеджера ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления, то в толстом клиенте, в режиме управляемого приложения, клиент-сервер, представление будет формироваться по умолчанию, без вызова этих обработчиков, и тем самым будет отличаться от остальных режимов работы. (При этом оставшиеся два обработчика модуля менеджера ОбработкаПолученияДанныхВыбора и ОбработкаПолученияФормы вызываются всегда только на сервере, поэтому указанное ограничение на них не распространяется.)

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      3. В тех случаях, когда требуется снять указанное выше ограничение, необходимо дополнительно обеспечить работу на клиенте следующих фрагментов серверного кода:

      \n
        \n
      • обработчиков событий модулей менеджеров ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления \n
      • а также код подписок на эти события модулей менеджеров.
      \n

      Для этого код перечисленных обработчиков событий следует вынести за инструкции препроцессора, указанные в п.2, а обработчики подписок разместить в клиент-серверных модулях.

      \n

      При необходимости вызова серверных процедур (и функций) из клиентского кода следует размещать вызываемые процедуры в серверных общих модулях с признаком Вызов сервера. При этом нужно убедиться, что в параметры процедур (и в возвращаемые значения функций) не передаются значения мутабельных типов (СправочникОбъект, ДокументОбъект и пр.)

      \n

      Важно: не следует для этих целей всем общим модулям с признаком Сервер принудительно устанавливать флажок Вызов сервера. Подробнее см. Ограничение на установку признака «Вызов сервера» у общих модулей.

      \n

      Например, обработчик события ОбработкаПолученияПредставления вызывает общий модуль, который не доступен на клиенте:

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
       
        Взаимодействия.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;
       
      КонецПроцедуры

      \n

      правильно выполнить переход на сервер (и при этом не передавать на клиент значения мутабельных типов):

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)

        ВзаимодействияВызовСервера.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;

      \n

      КонецПроцедуры

      \n

      4. Для расстановки фрагментов кода с инструкциями препроцессора можно воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "259", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Имя неверно образовано из синонима с префиксом \"(не используется)\".", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "261", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Свойство \"Положение строки поиска\" динамических списков должно быть установлено в значение \"Нет\".", +"Description": "

      Ограничения при использовании динамических списков

      #std489

      Область применения: управляемое приложение, мобильное приложение.

      \n

      1.1. При разработке интерфейса, разработчик может использовать группировки в динамических списках (cм. Группировки в списках).
      Разработчик может:

      \n
        \n
      • установить в настройках динамического списка группировки по умолчанию; \n
      • добавить на форму специальные элементы управления (команды меню, поля выбора для «быстрой» группировки и т.п.), которые предоставляют пользователю возможность устанавливать группировки.
      \n

      В данном стандарте перечислены условия, которые должен соблюсти разработчик, если он тем или иным способом управляет группировками динамических списков.

      \n

      1.2. Пользователь, при помощи настройки списка может установить свои группировки – в этом случае прикладной разработчик не может (и не должен) гарантировать оптимальную производительность.

      \n

      1.3. Использование группировок рекомендуется в тех динамических списках, в которых заведомо небольшое число записей (не более нескольких сотен). Небольшое число записей может обеспечиваться отбором, примененным в запросе динамического списка или отбором, применяемым к динамическому списку в форме и действие которого пользователь не может отменить.

      \n

      1.4. В динамических списках, которые отображают таблицы с большим количеством записей, группировка может осуществляться только по проиндексированным полям.

      \n

      Требование связано со следующими особенностями работы динамического списка. Для построения группировки, динамическому списку необходимо выбрать все уникальные из таблицы базы данных значения поля, по которому строится группировка. Затем производится сортировка и вывод пользователю. Когда пользователь раскрывает значение группировки, динамический список выбирает все записи таблицы с заданным значением в поле.

      \n

      1.5. Допускается делать многоуровневые группировки в динамических списках только при соблюдении следующих условий:

      \n
        \n
      • поле, по которому осуществляется первая группировка, должно быть проиндексировано; \n
      • поле, по которому осуществляется первая группировка, должно обладать хорошей селективностью (т.е. для каждому значению этого поля должно соответствовать небольшое количество записей в таблице базы данных);
      \n

      Эти требования связаны с тем, что раскрытие пользователем последующих (после первой) группировок динамический список будет отрабатывать уже без использования индексов, по всем элементам, отобранным по первой группировке.

      \n

      1.6. Не рекомендуется делать группировки по полям, которые являются характеристиками объекта метаданных. Это ограничение связано с тем, что при выводе характеристик делается ЛЕВОЕ СОЕДИНЕНИЕ с таблицей характеристик, поэтому запрос с отбором по одной характеристике будет не эффективным даже при наличии индекса (в любом случае будет сканирование по главной таблице).

      \n

      2. Для иерархических списков не рекомендуется устанавливать свойство НачальноеОтображениеДерева в значение РаскрыватьВсеУровни, так как это приведет к критичному снижению скорости открытия больших списков. Следует  использовать значения НеРаскрывать или РаскрыватьВерхнийУровень.

      \n

      Дополнительную информацию об особенностях динамических списков можно получить в документации по платформе (см. Динамический список)

      \n

      3. Строку поиска в командной панели динамического списка допустимо отключать в тех случаях, когда с его помощью не выполняются основные сценарии поиска. Например, в списке номенклатуры важен поиск по части артикула, что не поддерживается механизмом поиска.

      \n

      Это ограничение обусловлено тем, что почти всегда поиск (когда он использует технологию полнотекстового поиска) работает только с начала слов. При этом в версиях платформы 1С:Предприятие 8.3.7 и ранее у данного механизма имеется еще более ограничений (в частности, в поисковую выдачу не попадали элементы, которые еще не были проиндексированы и т.п.).

      \n

      Для отключения строки поиска в командной панели необходимо свойства ПоложениеСтрокиПоиска и ПоложениеУправленияПоиском динамических списков установить в значение Нет (для форм, созданных в предыдущих версиях платформы, значение Нет уже установлено по умолчанию).

      \n
      \n

      См. также: Запросы в динамических списках

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "262", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Свойство \"Положение управления поиском\" динамических списков должно быть установлено в значение \"Нет\".", +"Description": "

      Ограничения при использовании динамических списков

      #std489

      Область применения: управляемое приложение, мобильное приложение.

      \n

      1.1. При разработке интерфейса, разработчик может использовать группировки в динамических списках (cм. Группировки в списках).
      Разработчик может:

      \n
        \n
      • установить в настройках динамического списка группировки по умолчанию; \n
      • добавить на форму специальные элементы управления (команды меню, поля выбора для «быстрой» группировки и т.п.), которые предоставляют пользователю возможность устанавливать группировки.
      \n

      В данном стандарте перечислены условия, которые должен соблюсти разработчик, если он тем или иным способом управляет группировками динамических списков.

      \n

      1.2. Пользователь, при помощи настройки списка может установить свои группировки – в этом случае прикладной разработчик не может (и не должен) гарантировать оптимальную производительность.

      \n

      1.3. Использование группировок рекомендуется в тех динамических списках, в которых заведомо небольшое число записей (не более нескольких сотен). Небольшое число записей может обеспечиваться отбором, примененным в запросе динамического списка или отбором, применяемым к динамическому списку в форме и действие которого пользователь не может отменить.

      \n

      1.4. В динамических списках, которые отображают таблицы с большим количеством записей, группировка может осуществляться только по проиндексированным полям.

      \n

      Требование связано со следующими особенностями работы динамического списка. Для построения группировки, динамическому списку необходимо выбрать все уникальные из таблицы базы данных значения поля, по которому строится группировка. Затем производится сортировка и вывод пользователю. Когда пользователь раскрывает значение группировки, динамический список выбирает все записи таблицы с заданным значением в поле.

      \n

      1.5. Допускается делать многоуровневые группировки в динамических списках только при соблюдении следующих условий:

      \n
        \n
      • поле, по которому осуществляется первая группировка, должно быть проиндексировано; \n
      • поле, по которому осуществляется первая группировка, должно обладать хорошей селективностью (т.е. для каждому значению этого поля должно соответствовать небольшое количество записей в таблице базы данных);
      \n

      Эти требования связаны с тем, что раскрытие пользователем последующих (после первой) группировок динамический список будет отрабатывать уже без использования индексов, по всем элементам, отобранным по первой группировке.

      \n

      1.6. Не рекомендуется делать группировки по полям, которые являются характеристиками объекта метаданных. Это ограничение связано с тем, что при выводе характеристик делается ЛЕВОЕ СОЕДИНЕНИЕ с таблицей характеристик, поэтому запрос с отбором по одной характеристике будет не эффективным даже при наличии индекса (в любом случае будет сканирование по главной таблице).

      \n

      2. Для иерархических списков не рекомендуется устанавливать свойство НачальноеОтображениеДерева в значение РаскрыватьВсеУровни, так как это приведет к критичному снижению скорости открытия больших списков. Следует  использовать значения НеРаскрывать или РаскрыватьВерхнийУровень.

      \n

      Дополнительную информацию об особенностях динамических списков можно получить в документации по платформе (см. Динамический список)

      \n

      3. Строку поиска в командной панели динамического списка допустимо отключать в тех случаях, когда с его помощью не выполняются основные сценарии поиска. Например, в списке номенклатуры важен поиск по части артикула, что не поддерживается механизмом поиска.

      \n

      Это ограничение обусловлено тем, что почти всегда поиск (когда он использует технологию полнотекстового поиска) работает только с начала слов. При этом в версиях платформы 1С:Предприятие 8.3.7 и ранее у данного механизма имеется еще более ограничений (в частности, в поисковую выдачу не попадали элементы, которые еще не были проиндексированы и т.п.).

      \n

      Для отключения строки поиска в командной панели необходимо свойства ПоложениеСтрокиПоиска и ПоложениеУправленияПоиском динамических списков установить в значение Нет (для форм, созданных в предыдущих версиях платформы, значение Нет уже установлено по умолчанию).

      \n
      \n

      См. также: Запросы в динамических списках

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "263", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Неверно снят флажок \"Включать в командный интерфейс\". Для подсистемы, включенной в пользовательский командный интерфейс, он должен быть установлен.", +"Description": "

      Использование подсистем

      #std543

      Область применения: управляемое приложение, обычное приложение.

      \n

      Методическая рекомендация (полезный совет)

      \n

      1.1. С помощью подсистем решаются две методические задачи:

      \n
        \n
      • \n
        Сформировать глобальный командный интерфейс основного окна приложения, которое дает пользователю представление о функциональности приложения в целом.
        \n
      • \n
        Сгруппировать объекты метаданных по функциональному признаку для удобства разработки.
      \n

      В простейшем случае, получившаяся для обоих задач структура подсистем конфигурации может совпадать.

      \n

      \n

      Например, видимые для пользователей разделы командного интерфейса «Закупки», «Продажи» и пр. могут использоваться одновременно и при разработке: для быстрого отбора объектов в окне метаданных Конфигуратора, при переносе объектов в другие конфигурации, для задания ограничений области поиска при глобальном поиске по конфигурации и т.д.

      \n

      У таких подсистем должен быть установлен флажок Включать в командный интерфейс.

      \n

      1.2. В общем случае, подсистема, логически объединяющая некоторый набор объектов метаданных, может не совпадать с одним разделом командного интерфейса приложения. Для логического объединения набора объектов метаданных по функциональному признаку рекомендуется заводить в конфигурации отдельную иерархию подсистем, не включенных в командный интерфейс. У таких «функциональных» подсистем флажок Включать в командный интерфейс должен быть снят.

      \n

      Примеры:

      \n
        \n
      • \n
        справочник Номенклатура логически относится к одной «функциональной» подсистеме «Нормативно-справочная информация», но доступен в командном интерфейсе одновременно в двух разделах – «Нормативно-справочная информация» и «Маркетинг»
        \n
      • \n
        в раздел командного интерфейса «Настройка и администрирование» помещаются команды открытия списков объектов, логически относящихся к тем «функциональным» подсистемам конфигурации, которые предоставляют возможность настройки для администратора системы.
      \n

      1.3. При этом, общие модули, регламентные задания, константы, подписки на события и прочие объекты, не имеющие визуального представления в командном интерфейсе, рекомендуется включать только в состав «функциональных» подсистем.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "264", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Неверно установлен флажок \"Включать в командный интерфейс\". Для функциональной подсистемы он должен быть снят.", +"Description": "

      Использование подсистем

      #std543

      Область применения: управляемое приложение, обычное приложение.

      \n

      Методическая рекомендация (полезный совет)

      \n

      1.1. С помощью подсистем решаются две методические задачи:

      \n
        \n
      • \n
        Сформировать глобальный командный интерфейс основного окна приложения, которое дает пользователю представление о функциональности приложения в целом.
        \n
      • \n
        Сгруппировать объекты метаданных по функциональному признаку для удобства разработки.
      \n

      В простейшем случае, получившаяся для обоих задач структура подсистем конфигурации может совпадать.

      \n

      \n

      Например, видимые для пользователей разделы командного интерфейса «Закупки», «Продажи» и пр. могут использоваться одновременно и при разработке: для быстрого отбора объектов в окне метаданных Конфигуратора, при переносе объектов в другие конфигурации, для задания ограничений области поиска при глобальном поиске по конфигурации и т.д.

      \n

      У таких подсистем должен быть установлен флажок Включать в командный интерфейс.

      \n

      1.2. В общем случае, подсистема, логически объединяющая некоторый набор объектов метаданных, может не совпадать с одним разделом командного интерфейса приложения. Для логического объединения набора объектов метаданных по функциональному признаку рекомендуется заводить в конфигурации отдельную иерархию подсистем, не включенных в командный интерфейс. У таких «функциональных» подсистем флажок Включать в командный интерфейс должен быть снят.

      \n

      Примеры:

      \n
        \n
      • \n
        справочник Номенклатура логически относится к одной «функциональной» подсистеме «Нормативно-справочная информация», но доступен в командном интерфейсе одновременно в двух разделах – «Нормативно-справочная информация» и «Маркетинг»
        \n
      • \n
        в раздел командного интерфейса «Настройка и администрирование» помещаются команды открытия списков объектов, логически относящихся к тем «функциональным» подсистемам конфигурации, которые предоставляют возможность настройки для администратора системы.
      \n

      1.3. При этом, общие модули, регламентные задания, константы, подписки на события и прочие объекты, не имеющие визуального представления в командном интерфейсе, рекомендуется включать только в состав «функциональных» подсистем.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "265", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в имени объекта метаданных.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "267", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Количество параметров вызова процедуры или функции не соответствует количеству параметров ее определения.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "269", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Обращение к несуществующей подсистеме.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "271", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обращение к несуществующему общему модулю.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "273", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "В структуре модуля присутствуют пустые области.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "274", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Неправильный порядок стандартных областей в коде.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "275", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Обращение к несуществующему элементу формы.", +"Description": "Нет описания", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "277", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Недопустимый вызов служебной процедуры или функции другой подсистемы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      \n\n\n

      Обеспечение совместимости библиотек

      #std644

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

      \n

      Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

      \n

      Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

      \n

      Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

      \n

      1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Что изменилось в новой версии?РР.ПП.ВВ.СС
      Архитектурные изменения,
      нарушена совместимость
      (есть инструкция по переходу)
      vvxx
      Новые функцииvvvx
      Исправлены ошибкиvvvv

      \n

      Здесь:

      \n
        \n
      1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
      2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
      3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
      4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
      \n

      Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

      \n

      1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

      \n

      1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

      \n

      1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

      \n

      1.5. В целях обеспечения совместимости следует

      \n
        \n
      • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
      • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
      \n

      Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

      \n\n

      1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

      \n
        \n
      • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
      • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
      • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
      \n

      1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

      \n
        \n
      • добавление новой функции в программный модуль;  \n
      • добавление процедуры в переопределяемый модуль; \n
      • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
      • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
      \n

      В то же время:

      \n
        \n
      • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
      • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
          \n
        • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
      \n

      1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
      Примеры фрагментов документации:

      \n
        \n
      • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
      • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
      • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
      • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
      • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
      \n

      1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

      \n

      2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

      \n

      При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
      Например:

      \n
        \n
      • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
      • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
      \n

      Такое размещение программного интерфейса в отдельных общих модулях позволяет

      \n
        \n
      • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
      • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
      \n

      2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

      \n

      Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

      \n

      #Область ПрограммныйИнтерфейс
      //Код процедур и функций

      \n

      #Область ДляВызоваИзДругихПодсистем

      \n

      // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
      // Код процедур и функций
      // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

      \n

      // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
      // Код процедур и функций
      // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

      \n

      #КонецОбласти

      \n

      #КонецОбласти

      \n

      Англоязычный вариант синтаксиса:

      \n

      #Region Public
      // Enter code here.

      \n

      #Region InterfaceImplementation

      \n

      // StandardSubsystems.BatchObjectModification
      // Enter code here.
      // End StandardSubsystems.BatchObjectModification

      \n

      // SaaSTechnology.DataExportImport
      // Enter code here.
      // End SaaSTechnology.DataExportImport

      \n

      #EndRegion

      \n

      #EndRegion

      \n

      3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

      \n

      3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

      \n

      // Устарела: Следует использовать функцию ПересчитатьПоКурсу
      // …
      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

      \n

      (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

      \n

      и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

      \n

      При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

      \n

      В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

      \n

      По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

      \n
        \n
      • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
      \n

      3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

      \n

      Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

      \n

      Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

      \n

      3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
      Например:

      \n

      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

      \n

      При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

      \n

      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

      \n

      Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

      \n

      3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

      \n

      Процедура ПриОпределенииНастроек(Настройки) Экспорт
       Настройки.ВыводитьОписания = Истина;
       Настройки.События.ПриСозданииНаСервере = Истина;
       Настройки.... = ...;
      КонецПроцедуры

      \n

      Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

      \n

      3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

      \n

      Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

      \n

       Запрос = Новый Запрос;
       Запрос.Текст = \"ВЫБРАТЬ
                      | ОбластиДанных.Представление
                      |ИЗ
                      | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                      |ГДЕ
                      | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
       Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
       ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
       ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

      \n

      следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

      \n

      ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

      \n

      При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

      \n

      3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

      \n
        \n
      • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
      • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
      \n

      В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

      \n

      4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

      \n\n\n

      Разработка конфигураций с повторным использованием общего кода и объектов метаданных

      #std551

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Методическая рекомендация (полезный совет)

      \n

      1. В условиях разработки нескольких конфигураций (например, линейки продуктов) возникает задача повторного использования общего кода и объектов конфигурации. Эту задачу рекомендуется решать с использованием вспомогательных конфигураций – библиотек.

      \n

      Библиотечная конфигурация (библиотека) – это конфигурация, которая в отличие от «обычных» прикладных решений не предназначена для использования конечными пользователями, а служит только для поддержки конфигураций, пользующихся ее функциональностью. В них размещается функциональность, общая для прикладных решений.

      \n

      Библиотечный подход к разработке общей функциональности прикладных решений позволяет:

      \n
        \n
      • вести разработку общей функциональности централизованно (а не в каждом прикладном решении «по месту»); \n
      • выпускать версии общей функциональности в виде продукта (дистрибутива или файла поставки библиотеки); \n
      • повторно использовать код и объекты библиотеки в конфигурациях с помощью механизма постановки на поддержку платформы 1С:Предприятия; \n
      • унифицировать конфигурации по набору общих объектов метаданных и функциональных подсистем.
      \n

      2. В свою очередь, библиотека может стоять на поддержке у другой библиотеки, образуя таким образом иерархию библиотек. Библиотечная конфигурация, которая стоит на поддержке у другой библиотеки (библиотеки-родителя), называется библиотекой-наследником.

      \n

      Как правило, библиотеки не являются самостоятельным предметом разработки, а предназначены только для создания прикладных решений. Таким образом, прикладные решения являются конечными конфигурациями-потребителями в иерархии библиотек.

      \n

      3. При взаимодействии конфигураций, библиотек и внешних потребителей следует выделять следующие области видимости программного кода:

      \n
      \n

      1. Программный интерфейс содержит экспортные процедуры и функции, предназначенные для использования сторонними потребителями. Программный интерфейс можно разделить на две категории:

      \n
      \n

      а) Программный интерфейс для использования любыми внешними потребителями предназначен для вызова из произвольного места в коде конфигурации. Потребителями такого программного интерфейса чаще всего выступают расширения конфигурации, сторонние доработки конфигурации или другие программы.

      \n

      б) Программный интерфейс для конкретных потребителей должен располагаться в определенном месте в коде конфигурации, определенном в документации, и может быть вызван только определенным потребителем. Такой программный интерфейс рекомендуется размещать в отдельном подразделе Для вызова из других подсистем. Подробнее см. стандарт Обеспечение обратной совместимости библиотек.

      \n

      2. Служебный программный интерфейс предназначен для экспортных процедур и функций, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки (конфигурации).
      3. Служебные процедуры и функции содержат внутреннюю реализацию функциональной подсистемы. Экспортные процедуры и функции, расположенные в этом разделе, предназначены только для вызова из других объектов этой же подсистемы.

      \n

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "278", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Недопустимый вызов служебного программного интерфейса.", +"Description": "

      Обеспечение совместимости библиотек

      #std644

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

      \n

      Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

      \n

      Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

      \n

      Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

      \n

      1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Что изменилось в новой версии?РР.ПП.ВВ.СС
      Архитектурные изменения,
      нарушена совместимость
      (есть инструкция по переходу)
      vvxx
      Новые функцииvvvx
      Исправлены ошибкиvvvv

      \n

      Здесь:

      \n
        \n
      1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
      2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
      3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
      4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
      \n

      Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

      \n

      1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

      \n

      1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

      \n

      1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

      \n

      1.5. В целях обеспечения совместимости следует

      \n
        \n
      • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
      • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
      \n

      Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

      \n\n

      1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

      \n
        \n
      • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
      • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
      • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
      \n

      1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

      \n
        \n
      • добавление новой функции в программный модуль;  \n
      • добавление процедуры в переопределяемый модуль; \n
      • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
      • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
      \n

      В то же время:

      \n
        \n
      • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
      • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
          \n
        • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
      \n

      1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
      Примеры фрагментов документации:

      \n
        \n
      • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
      • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
      • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
      • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
      • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
      \n

      1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

      \n

      2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

      \n

      При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
      Например:

      \n
        \n
      • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
      • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
      \n

      Такое размещение программного интерфейса в отдельных общих модулях позволяет

      \n
        \n
      • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
      • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
      \n

      2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

      \n

      Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

      \n

      #Область ПрограммныйИнтерфейс
      //Код процедур и функций

      \n

      #Область ДляВызоваИзДругихПодсистем

      \n

      // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
      // Код процедур и функций
      // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

      \n

      // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
      // Код процедур и функций
      // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

      \n

      #КонецОбласти

      \n

      #КонецОбласти

      \n

      Англоязычный вариант синтаксиса:

      \n

      #Region Public
      // Enter code here.

      \n

      #Region InterfaceImplementation

      \n

      // StandardSubsystems.BatchObjectModification
      // Enter code here.
      // End StandardSubsystems.BatchObjectModification

      \n

      // SaaSTechnology.DataExportImport
      // Enter code here.
      // End SaaSTechnology.DataExportImport

      \n

      #EndRegion

      \n

      #EndRegion

      \n

      3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

      \n

      3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

      \n

      // Устарела: Следует использовать функцию ПересчитатьПоКурсу
      // …
      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

      \n

      (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

      \n

      и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

      \n

      При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

      \n

      В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

      \n

      По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

      \n
        \n
      • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
      \n

      3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

      \n

      Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

      \n

      Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

      \n

      3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
      Например:

      \n

      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

      \n

      При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

      \n

      Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

      \n

      Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

      \n

      3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

      \n

      Процедура ПриОпределенииНастроек(Настройки) Экспорт
       Настройки.ВыводитьОписания = Истина;
       Настройки.События.ПриСозданииНаСервере = Истина;
       Настройки.... = ...;
      КонецПроцедуры

      \n

      Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

      \n

      3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

      \n

      Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

      \n

       Запрос = Новый Запрос;
       Запрос.Текст = \"ВЫБРАТЬ
                      | ОбластиДанных.Представление
                      |ИЗ
                      | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                      |ГДЕ
                      | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
       Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
       ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
       ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

      \n

      следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

      \n

      ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

      \n

      При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

      \n

      3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

      \n
        \n
      • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
      • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
      \n

      В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

      \n

      4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

      \n\n\n

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      \n\n\n

      Разработка конфигураций с повторным использованием общего кода и объектов метаданных

      #std551

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Методическая рекомендация (полезный совет)

      \n

      1. В условиях разработки нескольких конфигураций (например, линейки продуктов) возникает задача повторного использования общего кода и объектов конфигурации. Эту задачу рекомендуется решать с использованием вспомогательных конфигураций – библиотек.

      \n

      Библиотечная конфигурация (библиотека) – это конфигурация, которая в отличие от «обычных» прикладных решений не предназначена для использования конечными пользователями, а служит только для поддержки конфигураций, пользующихся ее функциональностью. В них размещается функциональность, общая для прикладных решений.

      \n

      Библиотечный подход к разработке общей функциональности прикладных решений позволяет:

      \n
        \n
      • вести разработку общей функциональности централизованно (а не в каждом прикладном решении «по месту»); \n
      • выпускать версии общей функциональности в виде продукта (дистрибутива или файла поставки библиотеки); \n
      • повторно использовать код и объекты библиотеки в конфигурациях с помощью механизма постановки на поддержку платформы 1С:Предприятия; \n
      • унифицировать конфигурации по набору общих объектов метаданных и функциональных подсистем.
      \n

      2. В свою очередь, библиотека может стоять на поддержке у другой библиотеки, образуя таким образом иерархию библиотек. Библиотечная конфигурация, которая стоит на поддержке у другой библиотеки (библиотеки-родителя), называется библиотекой-наследником.

      \n

      Как правило, библиотеки не являются самостоятельным предметом разработки, а предназначены только для создания прикладных решений. Таким образом, прикладные решения являются конечными конфигурациями-потребителями в иерархии библиотек.

      \n

      3. При взаимодействии конфигураций, библиотек и внешних потребителей следует выделять следующие области видимости программного кода:

      \n
      \n

      1. Программный интерфейс содержит экспортные процедуры и функции, предназначенные для использования сторонними потребителями. Программный интерфейс можно разделить на две категории:

      \n
      \n

      а) Программный интерфейс для использования любыми внешними потребителями предназначен для вызова из произвольного места в коде конфигурации. Потребителями такого программного интерфейса чаще всего выступают расширения конфигурации, сторонние доработки конфигурации или другие программы.

      \n

      б) Программный интерфейс для конкретных потребителей должен располагаться в определенном месте в коде конфигурации, определенном в документации, и может быть вызван только определенным потребителем. Такой программный интерфейс рекомендуется размещать в отдельном подразделе Для вызова из других подсистем. Подробнее см. стандарт Обеспечение обратной совместимости библиотек.

      \n

      2. Служебный программный интерфейс предназначен для экспортных процедур и функций, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки (конфигурации).
      3. Служебные процедуры и функции содержат внутреннюю реализацию функциональной подсистемы. Экспортные процедуры и функции, расположенные в этом разделе, предназначены только для вызова из других объектов этой же подсистемы.

      \n

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "280", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Конструкция \"Попытка...Исключение...КонецПопытки\" не содержит кода в исключении.", +"Description": "

      Перехват исключений в коде

      #std499

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В общем случае не рекомендуется перехватывать исключения. В частности не нужно перехватывать исключения только ради выдачи сообщения об ошибке. Необработанное исключение в любом случае будет выдано пользователю в виде сообщения об ошибке (а также будет записано в журнал регистрации для администратора, если исключение возникло на сервере).

      \n

      2. Тем не менее, необходимость перехвата исключений в коде все же возникает. Например, для того чтобы уточнить текст ошибки, дополнив его прикладной, понятной конечному пользователю, информацией. Однако при этом необходимо фиксировать причину ошибки в журнале регистрации для того, чтобы системный администратор имел возможность выполнить диагностику проблемы и при необходимости передать информацию об ошибке в службу технической поддержки.

      \n

      При этом рекомендуется записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю.

      \n

      3. Частные случаи некорректного использования и перехвата исключений.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      3.1. Если имеется некоторая серверная бизнес-логика, которая вызывается с клиента при интерактивной работе пользователя:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то неправильно маскировать от пользователя и администратора исходную проблему:

      \n

      // на клиенте
      Попытка
          ВыполнитьОперацию();
      Исключение
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена.'\"));
      КонецПопытки;

      \n

      Правильно записывать в журнал регистрации подробное представление исключения, а краткое представление добавлять в текст сообщения пользователю:

      \n

      &НаСервере
      Процедура ВыполнитьОперацию()
        Попытка
          // код, приводящий к вызову исключения
          ....
        Исключение
          // Запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
          ВызватьИсключение;
        КонецПопытки;
      КонецПроцедуры

      \n

      и тогда на клиенте:

      \n

      Попытка
          ВыполнитьОперацию();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
      КонецПопытки;

      \n

      3.2. Не следует анализировать текст исключений с целью интерпретации причины ошибки. Текст исключения может меняться в зависимости от локализации. В условиях отсутствия штатных средств (например, типизированных исключений), следует выдавать пользователю тексты исключений «как есть». Для понятности, его можно дополнить пояснением возможных причин.
      Например:

      \n

      Попытка
          ЗагрузитьФайлИзИнтернета(...);
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ТекстСообщения = НСтр(\"ru = 'Не удалось загрузить файл:'\") + Символы.ПС + ТекстСообщения + Символы.ПС + НСтр(\"ru = 'Возможные причины:
      • Нет подключения к Интернету;
      • На веб-узле возникли неполадки;
      • Брандмауэр или другое промежуточное ПО (антивирусы и т.п.) блокируют попытки программы подключиться к Интернету;
      • Подключение к Интернету выполняется через прокси-сервер, но его параметры не заданы в программе.'\");
          ПоказатьПредупреждение(,ТекстСообщения);
      КонецПопытки;

      \n

      В тех случаях, когда анализ типов исключений критически важен для корректной работы бизнес-логики, следует отказаться от исключений и использовать коды ошибок (коды возврата). При этом недопустимо использовать числовые коды ошибок, т.к. код становится нечитаемым:

      \n

      КодОшибки = ЗагрузитьФайлИзИнтернета(...);
      Если КодОшибки = 12345 Тогда
      ...
      ИначеЕсли ...

      \n

      правильно применять строковые литералы (например, \"Успешно\", \"НетМестаНаДиске\", \"Отменено\" и т.п.):

      \n

      РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(...);
      Если РезультатЗагрузки = \"Успешно\" Тогда
      ...
      ИначеЕсли ...

      \n

      Строковые литералы кодов ошибок не локализуются.

      \n

      Исключение составляют случаи работы с веб-сервисами и другими внешними системами, где коды ошибок не доступны, а результат работы транслируется в вызывающий код прикладной конфигурации в виде исключений.

      \n

      3.3. Если имеется некоторая клиентская бизнес-логика (код выполняется полностью на клиенте):

      \n

      &НаКлиенте
      Процедура СоздатьФайлНаДиске()
          // код, приводящий к вызову исключения
          ....
      КонецПроцедуры

      \n

      то рекомендуется делать дополнительный серверный вызов для протоколирования неудачного результата операции в журнал регистрации:

      \n

      Попытка
          // клиентский код, приводящий к вызову исключения
          СоздатьФайлНаДиске();
      Исключение
          ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
          ПоказатьПредупреждение(,НСтр(\"ru = 'Операция не может быть выполнена по причине:'\") + Символы.ПС + ТекстСообщения);
          ЗаписатьОшибкуРаботыСФайлами(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
      КонецПопытки;

      \n

      &НаСервереБезКонтекста
      Процедура ЗаписатьОшибкуРаботыСФайлами(...)
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки);
      КонецПроцедуры

      \n

      3.4. Недопустимо перехватывать любые исключения, бесследно для системного администратора:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение // перехват любых исключений
      КонецПопытки;

      \n

      Как правило, подобная конструкция скрывает реальную проблему, которую впоследствии невозможно диагностировать.
      Правильно:

      \n

      Попытка
          // код, приводящий к вызову исключения
          ....
      Исключение
          // Пояснение причин перехвата всех исключений \"незаметно\" от пользователя.
          // ....
          // И запись события в журнал регистрации для системного администратора.
          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
             УровеньЖурналаРегистрации.Ошибка,,,
             ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
      КонецПопытки;

      \n

      См. также Доступ к файловой системе из кода конфигурации, удаление временных файлов

      \n

      3.5. Недопустимо делать проверки наличия у объекта реквизитов, методов, макетов и т.п., используя для этого исключения, т.к. это может привести к сложно диагностируемым ошибкам, а также затрудняет отладку в режиме «Останавливаться по ошибке».
      Вместо перехвата исключений в этом случае рекомендуется:

      \n
        \n
      • использовать механизмы работы с метаданными, чтобы явным образом проверять наличие или отсутствие реквизита (макета и т.п.); \n
      • если различия связаны с особенностями встраивания библиотек – описывать особенности явным образом в переопределяемых модулях (см. Переопределяемые и поставляемые объекты); \n
      • пересмотреть логику работы методов, использующих перехват исключений. Например, можно предусмотреть параметры, которые определяются в вызывающем коде и указывают нужно или нет обращаться к какому-либо методу или свойству объекта.
      \n

      Например, неправильно:

      \n

      Попытка
       КонтекстЭДОСервер.ПолучитьМакет(\"КомпонентаОбмена\");
       ПутьВК = КонтекстЭДОСервер.ПутьКОбъекту +  \".Макет.КомпонентаОбмена\";
      Исключение
      КонецПопытки;

      \n

      Правильно:

      \n

      МакетКомпонентыОбмена = КонтекстЭДОСервер.Метаданные().Макеты.Найти(\"КомпонентаОбмена\");
      Если МакетКомпонентыОбмена <> Неопределено Тогда
       ПутьКМакету = КомпонентаОбмена.ПолноеИмя()
      КонецЕсли;

      \n

      3.6. Порядок обработки исключений при использовании транзакций описан в стандарте Транзакции: правила использования.

      \n

      3.7. Неправильно использовать исключения для приведения значения к типу. Для таких операций необходимо использовать возможности объекта ОписаниеТипов.

      \n

      Например, неправильно:

      \n

      Попытка
       КоличествоДнейРазрешения = Число(Значение);
      Исключение
       КоличествоДнейРазрешения = 0; // значение по умолчанию
      КонецПопытки;

      \n

      Правильно:

      \n

      ОписаниеТипа = Новый ОписаниеТипов(\"Число\");
      КоличествоДнейРазрешения = ОписаниеТипа.ПривестиЗначение(Значение);

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "282", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Закомментированный код или отсутствие пробела в комментарии после знака \"//\".", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "283", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Обращение к несуществующей роли.", +"Description": "В параметрах функций \"РольДоступна\" и \"Пользователи.РолиДоступны\" должны быть указаны существующие роли.", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "284", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "В тексте модуля содержатся служебные комментарии.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "285", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Закомментированный код содержит запрещенный символ.", +"Description": "

      Тексты модулей

      #std456

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Тексты модулей должны быть написаны на русском языке. 

      \n

      Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

      \n

      1.1. В текстах модулях не допускается использовать букву \"ё\".

      \n

      Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

      \n

      1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

      \n

      Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2. Программные модули не должны иметь неиспользуемых процедур и функций.

      \n

      3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

      Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
      \n

      также неправильно:

      Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
      \n

      Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

      \n

      4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

      НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
      \n

      5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

      \n

      Размер табуляции - стандартный (4 символа).

      5.1. С крайней левой позиции должны начинаться только:

      \n
        \n
      • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
      • операторы предварительного объявления процедур и функций;  \n
      • заголовки (описания) процедур и функций;  \n
      • объявление переменных модуля;  \n
      • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
      • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
      • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
      \n

      5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

      6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

      \n
      \n

      См. также: Перенос выражений.

      \n

      7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

      \n

      7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

      НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
      \n

      7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

      // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
      \n

      8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "286", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Стандартная область является вложенной.", +"Description": "

      Структура модуля

      #std455

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

      \n
        \n
      • заголовок модуля \n
      • раздел описания переменных \n
      • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
      • обработчики событий объекта (формы) \n
      • служебные процедуры и функции модуля \n
      • раздел инициализации
      \n

      Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

      \n

      Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

      \n

      1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

      \n

      1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

      \n

      1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
      • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
      • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

        Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
      \n

      русск.

      #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
      \n

      1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

      \n

      русск.

      #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
      • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
      • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
      \n

      1.6. Шаблон оформления разделов для модулей форм:

      \n

      русск.

      #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n
        \n
      • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
      • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
      • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
      • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n
      \n

      См. также: Правила создания модулей форм

      \n

      1.7. Шаблон оформления разделов для модулей команд:

      \n

      русск.

      #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
      \n

      англ.

      #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
      \n


      \n
        \n
      • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
      • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
      \n

      1.8. В модуле не должно быть пустых областей.

      \n

      2. Общие требования к разделам программных модулей.

      \n

      2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
      Например:

      ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
      \n

      Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

      \n

      2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

      \n

      Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
      Пример:

      \n

      русск.

      #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
      \n

      англ.

      #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
      \n

      2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

      \n

      2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

      \n
        \n
      • \n
        создать отдельную процедуру (функцию), выполняющую необходимые действия
        \n
      • \n
        для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
        \n
      • \n
        из каждого обработчика вызвать требуемую процедуру (функцию).
      \n

      Например, неправильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
      \n

      правильно:

      &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
      \n

      Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

      \n

      2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

      \n

      2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

      \n

      В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

      \n

      Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

      \n

      2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
      Например:

      \n

      русск.

      #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
      \n

      англ.

      #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
      \n


      \n

      Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "287", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Обращение к несуществующей процедуре (функции).", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "288", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Устаревшая функция содержит код.", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "289", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Устаревшая процедура содержит код.", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "290", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Неверно установлены права в роли для чтения.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "291", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Неверно установлены права в роли для изменения.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "293", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В конструкторе объекта типа \"Структура\" указано более 3-х значений свойств.", +"Description": "

      Использование объектов типа Структура

      #std693

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Требования, предъявляемые данным стандартом к Структурам, направлены на повышение читаемости кода и упрощение внесения изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях. Повышение читаемости кода в свою очередь ведет к уменьшению допускаемых при разработке ошибок и повышает качество прикладного решения.

      \n

      1. При создании объекта типа Структура не рекомендуется передавать в конструктор более 3-х значений свойств. Вместо этого рекомендуется использовать метод Вставить или присваивать значения свойствам явным образом

      \n

      Неправильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура(
         \"НеПомещатьНастройкиВСхемуКомпоновкиДанных,
         |НеРедактироватьСхемуКомпоновкиДанных,
         |НеНастраиватьУсловноеОформление,
         |НеНастраиватьВыбор,
         |НеНастраиватьПорядок,
         |АдресСхемыКомпоновкиДанных,
         |АдресНастроекКомпоновкиДанных,
         |УникальныйИдентификатор,
         |Заголовок\",
         Истина,
         Истина,
         Истина,
         Истина,
         Истина,
         ТекущиеДанные.АдресСхемыКомпоновкиДанных,
         ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
              АдресНастроекСхемыКомпоновкиДанных,
              ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных),
         УникальныйИдентификатор,
         ЗаголовокФормыНастройкиСхемыКомпоновкиДанных));

      \n

      Правильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура;

      \n

      ПараметрыФормыКомпоновки.Вставить(\"НеПомещатьНастройкиВСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьВыбор\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьПорядок\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"АдресСхемыКомпоновкиДанных\", ТекущиеДанные.АдресСхемыКомпоновкиДанных);
      ПараметрыФормыКомпоновки.Вставить(\"АдресНастроекКомпоновкиДанных\", ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
                                                                                                                               АдресНастроекСхемыКомпоновкиДанных,
                                                                                                                               ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных));
      ПараметрыФормыКомпоновки.Вставить(\"УникальныйИдентификатор \", УникальныйИдентификатор);
      ПараметрыФормыКомпоновки.Вставить(\"Заголовок\", ЗаголовокФормыНастройкиСхемыКомпоновкиДанных);

      \n

      2. Не рекомендуется в конструкторе структуры использовать конструкторы других объектов, если эти конструкторы принимают параметры. В частности в конструкторе одной структуры не рекомендуется создавать другие структуры с объявлением значений свойств.

      \n

      Неправильно

      \n

      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(
        Объект.Товары,
        Новый Структура(
        \"ЗаполнитьПризнакХарактеристикиИспользуются,
        |ЗаполнитьПризнакТипНоменклатуры, ЗаполнитьПризнакВариантОформленияПродажи\",
         Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"),
         Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"),
         Новый Структура(\"Номенклатура\", \"ВариантОформленияПродажи\")
        )
       );

      \n

      Правильно

      \n


      ПараметрыЗаполненияРеквизитов = Новый Структура;
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакХарактеристикиИспользуются\",
                                                                Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"));
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакТипНоменклатуры\",
                                                                Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"));
      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(Объект.Товары, 
                                                                ПараметрыЗаполненияРеквизитов);

      \n

      3. Не рекомендуется в конструкторе структуры вызывать функции с большим (более 3) количеством параметров.

      \n

      Неправильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\",
           ПодборТоваровКлиентСервер.ПараметрыТовара(),
           ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен),
           ЦенаЗакупкиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен));

      \n

      Правильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\");
      СведенияОТоваре.ПараметрыТовара           = ПодборТоваровКлиентСервер.ПараметрыТовара();
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ЦенаЗакупкиИОстаткиТовара.ЦенаЗакупкиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);

      \n


      См. также

      \n\n\n\n

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "294", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В конструкторе объекта типа \"Структура\" использован конструктор другого объекта с параметрами.", +"Description": "

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n\n\n\n

      Использование объектов типа Структура

      #std693

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Требования, предъявляемые данным стандартом к Структурам, направлены на повышение читаемости кода и упрощение внесения изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях. Повышение читаемости кода в свою очередь ведет к уменьшению допускаемых при разработке ошибок и повышает качество прикладного решения.

      \n

      1. При создании объекта типа Структура не рекомендуется передавать в конструктор более 3-х значений свойств. Вместо этого рекомендуется использовать метод Вставить или присваивать значения свойствам явным образом

      \n

      Неправильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура(
         \"НеПомещатьНастройкиВСхемуКомпоновкиДанных,
         |НеРедактироватьСхемуКомпоновкиДанных,
         |НеНастраиватьУсловноеОформление,
         |НеНастраиватьВыбор,
         |НеНастраиватьПорядок,
         |АдресСхемыКомпоновкиДанных,
         |АдресНастроекКомпоновкиДанных,
         |УникальныйИдентификатор,
         |Заголовок\",
         Истина,
         Истина,
         Истина,
         Истина,
         Истина,
         ТекущиеДанные.АдресСхемыКомпоновкиДанных,
         ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
              АдресНастроекСхемыКомпоновкиДанных,
              ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных),
         УникальныйИдентификатор,
         ЗаголовокФормыНастройкиСхемыКомпоновкиДанных));

      \n

      Правильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура;

      \n

      ПараметрыФормыКомпоновки.Вставить(\"НеПомещатьНастройкиВСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьВыбор\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьПорядок\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"АдресСхемыКомпоновкиДанных\", ТекущиеДанные.АдресСхемыКомпоновкиДанных);
      ПараметрыФормыКомпоновки.Вставить(\"АдресНастроекКомпоновкиДанных\", ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
                                                                                                                               АдресНастроекСхемыКомпоновкиДанных,
                                                                                                                               ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных));
      ПараметрыФормыКомпоновки.Вставить(\"УникальныйИдентификатор \", УникальныйИдентификатор);
      ПараметрыФормыКомпоновки.Вставить(\"Заголовок\", ЗаголовокФормыНастройкиСхемыКомпоновкиДанных);

      \n

      2. Не рекомендуется в конструкторе структуры использовать конструкторы других объектов, если эти конструкторы принимают параметры. В частности в конструкторе одной структуры не рекомендуется создавать другие структуры с объявлением значений свойств.

      \n

      Неправильно

      \n

      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(
        Объект.Товары,
        Новый Структура(
        \"ЗаполнитьПризнакХарактеристикиИспользуются,
        |ЗаполнитьПризнакТипНоменклатуры, ЗаполнитьПризнакВариантОформленияПродажи\",
         Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"),
         Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"),
         Новый Структура(\"Номенклатура\", \"ВариантОформленияПродажи\")
        )
       );

      \n

      Правильно

      \n


      ПараметрыЗаполненияРеквизитов = Новый Структура;
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакХарактеристикиИспользуются\",
                                                                Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"));
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакТипНоменклатуры\",
                                                                Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"));
      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(Объект.Товары, 
                                                                ПараметрыЗаполненияРеквизитов);

      \n

      3. Не рекомендуется в конструкторе структуры вызывать функции с большим (более 3) количеством параметров.

      \n

      Неправильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\",
           ПодборТоваровКлиентСервер.ПараметрыТовара(),
           ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен),
           ЦенаЗакупкиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен));

      \n

      Правильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\");
      СведенияОТоваре.ПараметрыТовара           = ПодборТоваровКлиентСервер.ПараметрыТовара();
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ЦенаЗакупкиИОстаткиТовара.ЦенаЗакупкиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);

      \n


      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "295", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В конструкторе объекта типа \"Структура\" использован вызов функции с количеством параметров более 3-х.", +"Description": "

      Использование объектов типа Структура

      #std693

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Требования, предъявляемые данным стандартом к Структурам, направлены на повышение читаемости кода и упрощение внесения изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях. Повышение читаемости кода в свою очередь ведет к уменьшению допускаемых при разработке ошибок и повышает качество прикладного решения.

      \n

      1. При создании объекта типа Структура не рекомендуется передавать в конструктор более 3-х значений свойств. Вместо этого рекомендуется использовать метод Вставить или присваивать значения свойствам явным образом

      \n

      Неправильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура(
         \"НеПомещатьНастройкиВСхемуКомпоновкиДанных,
         |НеРедактироватьСхемуКомпоновкиДанных,
         |НеНастраиватьУсловноеОформление,
         |НеНастраиватьВыбор,
         |НеНастраиватьПорядок,
         |АдресСхемыКомпоновкиДанных,
         |АдресНастроекКомпоновкиДанных,
         |УникальныйИдентификатор,
         |Заголовок\",
         Истина,
         Истина,
         Истина,
         Истина,
         Истина,
         ТекущиеДанные.АдресСхемыКомпоновкиДанных,
         ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
              АдресНастроекСхемыКомпоновкиДанных,
              ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных),
         УникальныйИдентификатор,
         ЗаголовокФормыНастройкиСхемыКомпоновкиДанных));

      \n

      Правильно

      \n

      ПараметрыФормыКомпоновки  = Новый Структура;

      \n

      ПараметрыФормыКомпоновки.Вставить(\"НеПомещатьНастройкиВСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеРедактироватьСхемуКомпоновкиДанных\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьВыбор\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"НеНастраиватьПорядок\", Истина);
      ПараметрыФормыКомпоновки.Вставить(\"АдресСхемыКомпоновкиДанных\", ТекущиеДанные.АдресСхемыКомпоновкиДанных);
      ПараметрыФормыКомпоновки.Вставить(\"АдресНастроекКомпоновкиДанных\", ?(АдресНастроекСхемыКомпоновкиДанных <> Неопределено,
                                                                                                                               АдресНастроекСхемыКомпоновкиДанных,
                                                                                                                               ТекущиеДанные.АдресНастроекСхемыКомпоновкиДанных));
      ПараметрыФормыКомпоновки.Вставить(\"УникальныйИдентификатор \", УникальныйИдентификатор);
      ПараметрыФормыКомпоновки.Вставить(\"Заголовок\", ЗаголовокФормыНастройкиСхемыКомпоновкиДанных);

      \n

      2. Не рекомендуется в конструкторе структуры использовать конструкторы других объектов, если эти конструкторы принимают параметры. В частности в конструкторе одной структуры не рекомендуется создавать другие структуры с объявлением значений свойств.

      \n

      Неправильно

      \n

      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(
        Объект.Товары,
        Новый Структура(
        \"ЗаполнитьПризнакХарактеристикиИспользуются,
        |ЗаполнитьПризнакТипНоменклатуры, ЗаполнитьПризнакВариантОформленияПродажи\",
         Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"),
         Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"),
         Новый Структура(\"Номенклатура\", \"ВариантОформленияПродажи\")
        )
       );

      \n

      Правильно

      \n


      ПараметрыЗаполненияРеквизитов = Новый Структура;
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакХарактеристикиИспользуются\",
                                                                Новый Структура(\"Номенклатура\", \"ХарактеристикиИспользуются\"));
      ПараметрыЗаполненияРеквизитов.Вставить(\"ЗаполнитьПризнакТипНоменклатуры\",
                                                                Новый Структура(\"Номенклатура\", \"ТипНоменклатуры\"));
      НоменклатураСервер.ЗаполнитьСлужебныеРеквизитыПоНоменклатуреВКоллекции(Объект.Товары, 
                                                                ПараметрыЗаполненияРеквизитов);

      \n

      3. Не рекомендуется в конструкторе структуры вызывать функции с большим (более 3) количеством параметров.

      \n

      Неправильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\",
           ПодборТоваровКлиентСервер.ПараметрыТовара(),
           ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен),
           ЦенаЗакупкиИОстаткиТовара(
            Номенклатура,
            Характеристика,
            Соглашение,
            Валюта,
            ВидыЦен));

      \n

      Правильно

      \n

      СведенияОТоваре = Новый Структура(\"ПараметрыТовара, ЦенаПродажиИОстаткиТовара, ЦенаЗакупкиИОстаткиТовара\");
      СведенияОТоваре.ПараметрыТовара           = ПодборТоваровКлиентСервер.ПараметрыТовара();
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ПодборТоваровВызовСервера.ЦенаПродажиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);
      СведенияОТоваре.ЦенаПродажиИОстаткиТовара = ЦенаЗакупкиИОстаткиТовара.ЦенаЗакупкиИОстаткиТовара(
              Номенклатура,
              Характеристика,
              Соглашение,
              Валюта,
              ВидыЦен);

      \n


      См. также

      \n\n\n\n

      Параметры процедур и функций

      #std640

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

      \n

      2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

      \n

      3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
      Например, неправильно:

      Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
      \n

      правильно сначала расположить основные параметры ДокументОбъект и Форма:

      Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
      \n

      4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
      Например:

      Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
      \n

      5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

      \n

      При необходимости передавать в функцию большое число параметров рекомендуется:

      \n
        \n
      • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
      • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
      \n

      Например, неправильно:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
      \n

      Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

      // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
      \n

      Другой пример. Неправильно:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

      // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
      \n

      6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
      В частности:

      \n

      6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
      Неправильно:

      СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
      \n

      Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

      АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
      \n

      В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
      Например:

      Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
      \n

      6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

      \n

      Неправильно:

      ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
      \n

      Правильно:

      ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
      \n

      7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

      \n

      Например, для вызова процедуры

      \n

      Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

      \n

      неправильно:

      ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
      \n

      правильно:

      ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "297", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Результат функции, возможно возвращающей логическое значение, сравнивается с логической константой.", +"Description": "

      Общие требования к построению конструкций встроенного языка

      #std441

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В конструкциях встроенного языка ключевые слова пишутся канонически (как в документации или Синтакс-помощнике).
      Правильно:

      \n

      КонецЕсли

      \n

      Неправильно:

      \n

      конецЕсли, КОНЕЦЕСЛИ, конецесли, Конецесли.

      \n

      2. При следовании друг за другом нескольких операторов присваивания, допускается выравнивать их следующим образом:

      \n

      ДиалогВыбора.ПолноеИмяФайла = ИмяФайла;
      ДиалогВыбора.Каталог        = ИмяПути;
      ДиалогВыбора.Заголовок      = НСтр(\"ru = 'Выберите файл со списком запросов'\");
      ДиалогВыбора.Фильтр         = НСтр(\"ru = 'Файлы запросов (*.sel)|*.sel|Все файлы (*.*)|*.*'\");
      ДиалогВыбора.Расширение     = \"sel\";

      \n

      При этом не следует выравнивать операторы одинаково по всему модулю - рекомендуется делать выравнивание только для операторов, расположенных рядом.

      3. Составные логические выражения в ЕслиКонецЕсли переносятся согласно правилам переноса выражений.

      \n

      4. Логические выражения и логические значения (например, результат функции, возвращающей логическое значение, переменные типа Булево и пр.) не следует проверять путем сравнения с литералами Истина и Ложь.
      Правильно:

      \n

      Если ЭтоНовый() Тогда

      \n

      Неправильно:

      \n

      Если ЭтоНовый() = Истина Тогда

      \n

      5. В тех случаях, когда требуется сравнивать результаты каких-либо выражений, следует предварительно присваивать результаты этих выражений промежуточным переменным, и сравнивать уже сами эти переменные.
      Правильно:

      \n

      Ответ = Вопрос(НСтр(\"ru = 'Данные еще не записаны. Записать?'\"), РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
      Если Ответ = КодВозвратаДиалога.Да Тогда
        Записать();
      Иначе
        Возврат;
      КонецЕсли;

      \n

      Неправильно:

      \n

      Если Вопрос(НСтр(\"ru = 'Данные еще не записаны. Записать?'\"), РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да) = КодВозвратаДиалога.Да Тогда
        Записать();
      Иначе
        Возврат;
      КонецЕсли;

      \n

      6. Необходимо использовать системные наборы значений везде, где возможно их применить, например, вместо Символ(10) следует использовать Символы.ПС.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "299", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Возможно, неиспользуемая экспортная процедура (функция).", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "302", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В начале процедуры обработки регламентного задания отсутствует вызов процедуры \"ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();\".", +"Description": "

      Общие требования к регламентным заданиям

      #std540

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В общем случае, регламентные задания следует использовать, когда необходимо выполнить определенные периодические или однократные действия в соответствии с расписанием.

      \n

      2. При этом если регламентные задания не требуется добавлять или удалять в зависимости от действий пользователя или логики конфигурации, следует использовать предопределенные регламентные задания. Такие задания автоматически создаются в информационной базе с тем расписанием и состоянием, которое было задано разработчиком в Конфигураторе. Примеры предопределенных регламентных заданий:

      \n
        \n
      • загрузка курсов валют; \n
      • извлечение текста для полнотекстового индексирования; \n
      • обновление агрегатов.
      \n

      3.1. Если выполнение регламентного задания зависит от включенных одной или нескольких функциональных опций (ФО), то необходимо программно управлять признаком предопределенного регламентного задания Использование в зависимости от установленных ФО. Иначе регламентное задание будет приводить к запуску сеанса, занимая вычислительные ресурсы сервера 1С:Предприятие.

      \n

      Например, имеем регламентное задание ПолучениеИОтправкаЭлектронныхПисем (с установленным флажком Использование), которое должно выполняться только в том случае, если установлена ФО ИспользоватьПочтовыйКлиент.

      \n

      Неправильно: создавать предопределенное регламентное задание, зависящее от ФО, с установленным флажком Использование.

      \n

      Правильно: снять флажок Использование и управлять использованием регламентного задания в зависимости от включения/выключения функциональной опции.
      Если в конфигурации используется подсистема «Регламентные задания» Библиотеки стандартых подсистем (БСП), то для такой настройки следует использовать процедуру ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

      \n

      Настройка = Настройки.Добавить();
      Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.ОбновлениеСтатусовДоставкиSMS;
      Настройка.ФункциональнаяОпция = Метаданные.ФункциональныеОпции.ИспользоватьПочтовыйКлиент;
      Настройка.ДоступноВМоделиСервиса = Ложь;

      \n

      После чего в состав определяемого типа МестоХраненияФункциональныхОпций необходимо добавить константы, соответствующие функциональным опциям, используемым для управления регламентными заданиями.

      \n

      Для конфигураций без БСП следует управлять использованием регламентного задания, разместив, например, в модуле менеджера значения константы ИспользоватьПочтовыйКлиент следующий код:

      \n

      Процедура ПриЗаписи(Отказ)
       
       Задание = РегламентныеЗадания.НайтиПредопределенное(Метаданные.РегламентныеЗадания.ПолучениеИОтправкаЭлектронныхПисем);
       
       Если Задание.Использование <> Значение Тогда
        Задание.Использование = Значение;
        Задание.Записать();
       КонецЕсли;
       
      КонецПроцедуры

      \n

      3.2. Дополнительно следует обезопасить выполнение регламентного задания, включенного через консоль или другим способом, минуя включение ФО, вставив в начало процедуры обработки регламентного задания следующий код:

      \n

      ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();
      Если НЕ ПолучитьФункциональнуюОпцию(\"ИспользоватьПочтовыйКлиент\") Тогда
       ВызватьИсключение НСтр(\"ru = 'Регламентное задание недоступно по функциональным опциям.'\");
      КонецЕсли;

      \n

      Если в конфигурации используется подсистема «Регламентные задания» БСП и настроены зависимости регламентных заданий от ФО (как указано в п.3.1), то вместо этого достаточно вставить вызов, как показано в п.6.

      \n

      4.1. Если выполнение регламентного задания зависит от данных информационной базы, то флажок Предопределенное у регламентного задания следует отключать.
      Например:

      \n
        \n
      • обмен данными с другими информационными базами должен проводиться с каждой базой по индивидуальному расписанию; \n
      • запуск каждой дополнительной обработки в базе требуется выполнять по отдельному расписанию.
      \n

      В этих случаях требуется создавать экземпляры регламентных заданий и параметризовать их объектами ИБ (например, узлами ИБ, элементами справочника Дополнительные обработки и т.п.) из кода на встроенном языке с помощью метода РегламентныеЗадания.СоздатьРегламентноеЗадание. При этом в свойстве Наименование необходимо указывать представление объекта, на основании которого создается регламентное задание. Например, есть рассылка отчетов (элемент справочника), расписание, которое было настроено в карточке рассылки и ее автор, тогда добавление на основании нее регламентного задания будет выглядеть так:

      \n

      // Снимаем ограничение, что только администратор может создавать регламентные задания.
      УстановитьПривилегированныйРежим(Истина);
      Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.РассылкаОтчетов);

      \n

      ПараметрыЗадания = Новый Массив;
      ПараметрыЗадания.Добавить(РассылкаОтчетов);
      Задание.Параметры = ПараметрыЗадания;

      \n

      Задание.ИмяПользователя = АвторРассылки;
      Задание.Использование = Истина;
      Задание.Наименование = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Рассылка отчетов: %1'\"), СокрЛП(РассылкаОтчетов);
      Задание.Расписание = РасписаниеРассылки; 
      Задание.Записать();

      \n

      4.2. Если в конфигурации используется подсистема «Регламентные задания» БСП, то необходимо также запрещать интерактивное создание и запуск параметризованных регламентных заданий из формы Регламентные и фоновые задания. Для этого необходимо указать такое задание в процедуре ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

      \n

      Настройка = Настройки.Добавить();
      Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.РассылкаОтчетов;
      Настройка.Параметризуется = Истина;

      \n

      Также выполнить п.6.

      \n

      5. Во избежание различных конфликтных ситуаций рекомендуется в копиях информационной базы автоматически блокировать все регламентные задания, обращающиеся к внешним ресурсам (рассылка почты, синхронизация данных с другими программами и т.п.). Например, если копия информационной базы была развернута для тестирования или передана в службу технической поддержки.

      \n

      Если в конфигурации используется подсистема «Регламентные задания» БСП, то для этого необходимо перечислить такие задания в процедуре ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

      \n

      Настройка = Настройки.Добавить();
      Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.РассылкаОтчетов;
      Настройка.РаботаетСВнешнимиРесурсами = Истина;

      \n

      И выполнить п.6. \n

      В этом случае при перемещении информационной базы администратору будет задан вопрос об отключении таких заданий. \n

      6. Если регламентное задание попадает под требования, описанные в пунктах 3.1, 4.2, 5 и используется подсистема «Регламентные задания» БСП, то вначале процедур обработчиков таких заданий необходимо помещать вызов: \n

      ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.<ИмяЗадания>); \n

      Первый параметр при этом заполнять обязательно. \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "304", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно установлено значение свойства \"ОбновлениеПредопределенныхДанных\".", +"Description": "

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "305", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Программный вызов метода \"УстановитьОбновлениеПредопределенныхДанных\" используется для переключения режима \"ОбновлениеПредопределенныхДанных\".", +"Description": "

      Использование предопределенных элементов

      #std697

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Действует для версии платформы 1С:Предприятие 8.3.3 и выше без режима совместимости с версией 8.2

      \n

      1.1. В справочниках, планах счетов, планах видов характеристик и планах видов расчета имеется возможность создавать предопределенные элементы автоматически или программно.

      \n

      1.2. В большинстве случаев, предопределенные элементы рекомендуется создавать автоматически, поскольку они постоянно нужны и требуется упростить обращение к этим элементам из кода.
      Например, предопределенная страна Россия в справочнике Страны мира, предопределенные профиль групп доступа Администратор и т.п.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета должно быть установлено значение Авто (по умолчанию), а также не следует допускать программных вызовов метода УстановитьОбновлениеПредопределенныхДанных этих объектов для переключения этого режима. \n
      • запретить удаление предопределенных элементов пользователями, выключив во всех ролях следующие права (по умолчанию выключены): \n
          \n
        • ИнтерактивноеУдалениеПредопределенныхДанных \n
        • ИнтерактивнаяПометкаУдаленияПредопределенныхДанных \n
        • ИнтерактивноеСнятиеПометкиУдаленияПредопределенныхДанных \n
        • ИнтерактивноеУдалениеПомеченныхПредопределенныхДанных
      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.3. Исключение составляют дочерние узлы РИБ, в котором предопределенные элементы автоматически не создаются (и не обновляются при изменении в метаданных), а должны быть переданы из главного узла вместе с изменениями конфигурации.

      \n

      При этом:

      \n

      а) конфигурация должна обеспечивать загрузку сообщения обмена в подчиненный узел РИБ до выполнения другого прикладного кода, который обращается к получаемым из главного узла предопределенным элементам;

      \n

      б) в прикладной логике загрузки данных из главного узла (обработчик события ПриПолученииДанныхОтГлавного, правила регистрации объектов) следует избегать обращений к предопределенным элементам, поскольку нет гарантии, что они уже были загружены из сообщения обмена;

      \n

      в) код обработчиков обновления ИБ, который обрабатывает предопределенные элементы, не должен выполняться в подчиненных узлах РИБ:

      \n

      Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
       // заполняем предопределенные элементы
       // ...
      КонецЕсли;

      \n

      При использовании в конфигурации подсистемы \"Обмен данными\" Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше требования (а) и (б) снимаются.

      \n

      1.4. Для таблиц с предопределенными элементами, которые не входят в состав плана обмена РИБ (и на которые не ссылаются другие таблицы, входящие в состав плана обмена РИБ) свойство ОбновлениеПредопределенныхДанных необходимо устанавливать в значение ОбновлятьАвтоматически.

      \n

      Значение Авто в этом случае не подходит, так как для подчиненного узла Авто означает НеОбновлятьАвтоматически, то есть предопределенные элементы таблицы автоматически созданы не будут.

      \n

      При включенном режиме совместимости с версией 8.3.3 также необходимо при первом запуске подчиненного узла РИБ (сразу после того, как была обновлена его конфигурация) устанавливать автоматическое обновление в данных с помощью вызова:

      \n

      Справочники.<ИмяСправочника>.УстановитьОбновлениеПредопределенныхДанных(ОбновлениеПредопределенныхДанных.ОбновлятьАвтоматически);

      \n

      2. В некоторых случаях, предопределенные элементы не требуется создавать автоматически, если их наличие зависит от какого-либо условия: включенной функциональной опции, режима работы программы и т.п.

      \n

      Например, те или иные предопределенные виды расчетов в плане видов расчета Начисления зависят от значений функциональных опций ИспользоватьУчетВремениСотрудниковВЧасах, ИспользоватьСдельныйЗаработок и др.

      \n

      Для этого

      \n
        \n
      • в свойстве ОбновлениеПредопределенныхДанных справочника, плана счетов, плана видов характеристик или плана видов расчета нужно установить в значение \"Не обновлять автоматически\" \n
      • предусмотреть код создания (и пометки недействительным) предопределенного элемента в зависимости от бизнес-логики, например:
      \n

      Если ПолучитьФункциональнуюОпцию(\"ИспользоватьУчетВремениСотрудниковВЧасах\") Тогда
       НачислениеОбъект = ПланыВидовРасчета.Начисления.СоздатьВидРасчета();
       НачислениеОбъект.ИмяПредопределенныхДанных = \"ОкладПоЧасам\";
       // ...
       НачислениеОбъект.Записать();
      КонецЕсли;  

      \n
        \n
      • учитывать в прикладном коде отсутствие предопределенных элементов в ИБ. В противном случае, при обращении к несуществующему предопределенному элементу из кода или текста запроса будет вызвано исключение:
      \n

        ... = ПланВидовРасчета.Начисления.ОкладПоЧасам;
        ... = ПредопределенноеЗначение(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше рекомендуется использовать функцию ПредопределенныйЭлемент общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая возвращает Неопределено для несуществующих в ИБ предопределенных элементов:

      \n

        ... = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(\"ПланВидовРасчета.Начисления.ОкладПоЧасам\");

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "307", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Название процедуры (функции) содержит описание типов принимаемых параметров или возвращаемых значений.", +"Description": "

      Имена процедур и функций

      #std647

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Правильный выбор имен процедур и функций очень важен для повышения читаемости кода. В большинстве случаев хорошо выбранное имя процедуры в сочетании с правильно подобранными именами параметров избавляют от необходимости ее как-то дополнительно описывать. В ряде случаев, сложности в выборе имени процедуры и (или) ее параметров свидетельствуют о неправильной архитектуре программного кода. И наоборот, если \"самодокументирующееся\" имя придумать легко, значит процедура спроектирована правильно.

      \n
      \n

      См. также: Описание процедур и функций

      \n

      2. Имена процедур, функций и формальных параметров следует образовывать от терминов предметной области таким образом, чтобы из имени было понятно назначение. Следует стремиться к тому, чтобы имена были \"говорящими\" (документировали сами себя).
      Например, неправильно:

      Функция ВыполнитьПроверку(Параметр1, Рекв, ТЗ)\nФункция ПолучитьМассивыРеквизитов(ХозяйственнаяОперация, МассивВсехРеквизитов, МассивРеквизитовОперации)\n
      \n

      Правильно:

      Функция РеквизитОбъектаЗаданногоТипа(Объект, ИмяРеквизита, ТипЗначения)\nФункция ЗаполнитьИменаРеквизитовПоХозяйственнойОперации(ХозяйственнаяОперация, ИменаВсеРеквизиты, ИменаРеквизитыОперации)\n
      \n

      3. Имена следует образовывать путем удаления пробелов между словами. При этом, каждое слово в имени пишется с прописной буквы. Предлоги и местоимения из одной буквы также пишутся прописными буквами.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      4. Не рекомендуется в названиях процедур и функций описывать типы принимаемых параметров и (или) возвращаемых значений.

      \n

      Например, неправильно:

      Функция ПолучитьМассивРолейСПравомДобавления()\nФункция ПолучитьСтруктуруДополнительныхНастроек()\n
      \n

      Правильно:

      Функция ИменаРолейСПравомДобавления()\nФункция ДополнительныеНастройки()
      \n

      Эта рекомендация справедлива в большинстве случаев за редким исключением, когда без описания типа возвращаемого значения не ясно назначение самой процедуры или функции.

      \n

      5. Имена процедур в общем случае, следует образовывать от неопределенной формы глагола, от сути выполняемого действия, например:

      Неправильно:

      Процедура ЗагрузкаКонтрагента()\n
      \n

      Правильно:

      Процедура ЗагрузитьКонтрагента()\n
      \n

      6.1. Имена функций в общем случае следует образовывать от описания возвращаемого значения.

      \n

      Неправильно:

      Функция ПолучитьПолноеИмяПользователя() \nФункция СоздатьПараметрыЗаполненияЦенПоставщика() \nФункция ОпределитьДатуНачалаСеанса()\n
      \n

      Правильно:

      Функция ПолноеИмяПользователя() \nФункция НовыеПараметрыЗаполненияЦенПоставщика() \nФункция ДатаНачалаСеанса()\n
      \n

      6.2. Если функция предназначена для создания какого-либо объекта, то рекомендуется в ее имени использовать слово \"Новый\". Например,
      Неправильно:

      Функция ДобавитьПолеФормы()\nФункция СоздатьЭлементСправочникаФайлы()\nФункция ПолучитьТаблицуКоманд()\n
      \n

      Правильно:

      Функция НовоеПолеФормы() \nФункция НовыйЭлементСправочникаФайлы()\nФункция НоваяТаблицаКоманд()\n
      \n

      6.3. Если функция выполняет проверку какого-то условия, то ее имя рекомендуется начитать со слова \"Это\" или использовать причастия.
      Неправильно:

      Функция ПроверитьПроведенностьДокумента()\nФункция ПроверитьИзменениеРеквизитовДокумента()\nФункция ВнешняяЗадача()\n
      \n

      Правильно:

      Функция ДокументПроведен()\nФункция РеквизитыДокументыИзменены()\nФункция ЭтоВнешняяЗадача()\n
      \n

      6.4. В имени функции рекомендуется использовать глаголы в неопределенной форме в тех случаях, когда для понимания назначения функции важно, каким образом было получено возвращаемое значение. Например:

      Функция ВыбратьДанныеПоПравилу(Правило, ПользовательскиеНастройки)\nФункция ПреобразоватьДанныеПоПравилу(НаборыДанных, ПараметрыПреобразования)
      \n

      6.5. Если выполнение функции предполагает, прежде всего, какое-либо действие, и при этом возврат значения не является ее основной задачей (например, это признак успешно выполненного действия), то имена таких функций следует образовывать от неопределенной формы глагола, как и для процедур.
      Например:

      Функция РазрешитьРедактированиеРеквизитовОбъекта(Форма) 
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "311", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Длина названия раздела превышает 35 символов.", +"Description": "

      Панель разделов

      #std712

      Область применения: управляемое приложение.

      \n

      Панель разделов может выводиться как в виде отдельной панели, так и в составе меню функций:

      \n

           

      \n

      1. Состав панели

      \n

       

      \n

      Панель разделов является \"лицом\" программы и имеет большое значение на этапе освоения, поэтому состав и порядок разделов следует проектировать с особой тщательностью. Количество и состав разделов должен соответствовать реальным участкам работ и областям деятельности так, как их видят пользователи.

      \n

       

      \n

      1.1. Раздел \"Главное\" по умолчанию присутствует во всех конфигурациях и располагается первым. В него рекомендуется добавлять команды перехода к объектам, относящимся ко всей конфигурации, и не включать объекты, относящиеся к конкретным разделам учета или областям деятельности.

      \n

       

      \n

      1.2. Списки с условно-постоянной информацией (справочники, регистры сведений, списки перечислений и другие), в командном интерфейсе можно размещать:

      \n

      ·         внутри раздела, с которым связан такой список (в конце меню или в \"См. также\")
      Например, список должностей в разделе Кадры

      \n

      ·         в специально выделенном разделе конфигурации. При этом в других разделах команды перехода к подобным спискам, как правило, не размещаются
      Например, разделы \"Справочники\", \"Настройки\", \"НСИ\".

      \n

      ·         в панели навигации формы списка с условно-постоянной информацией, которой они \"подчинены\"
      Например, \"Счета учета номенклатуры\" в панели навигации справочника \"Номенклатура\"

      \n

       

      \n

      Исключение составляют списки с условно-постоянной информацией, с которых начинаются бизнес-процессы. Такие списки рекомендуется помещать в группы меню соответствующего раздела.

      \n

      Например, справочник \"Сотрудники\" размещается в разделе \"Кадры\", потому что сначала в него вводится информация о работнике, а потом на основании этих данных создается приказ о приеме на работу и другие документы.

      \n

       

      \n

      1.3. Разделы для настройки, администрирования и выполнения сервисных действий следует располагать в конце панели.

      \n

       

      \n

      2. Названия разделов

      \n

       

      \n

      2.1. Общая длина названия раздела не должна превышать 35 знаков с учетом пробелов (это позволяет разместить название в 2 строки, при дальнейшем увеличении количества знаков появится многоточие). Лучше выбирать названия примерно одного размеры по ширине, чтобы они смотрелись единообразно и ровно.

      \n

       

      \n

      2.2. Старайтесь сделать названия разделов конкретными и запоминающимися. Назначение раздела должно быть понятно из его названия.

      \n

       

      \n

      2.3. По возможности не используйте длинные слова. При выборе названия рекомендуется комбинировать слова следующим образом:

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n
      \n

      Комбинация слов

      \n

      Пример

      \n

      Одно-два средних слова

      \n

      Продажи

      \n

      Зарплата и персонал

      \n

      Одно длинное и одно короткое

      \n

      Отчетность и справки

      \n

       

      \n

      Два коротких и одно длинное

      \n

       

      \n

      Учет, налоги, отчетность

      \n

       

      \n

      2.4. Используйте в названиях только общеупотребительные и соответствующие целевой аудитории сокращения и аббревиатуры.

      \n

      Например, \"НДС\" или \"МСФО\".

      \n

       

      \n

      При этом сокращение обязательно нужно расшифровать во всплывающей подсказке.

      \n

      Например, для названия раздела \"ОС и НМА\" появляется всплывающая подсказка \"Основные средства и нематериальные активы\"

      \n

       

      \n

      2.5. Не рекомендуется делать раздел с названием \"Сервис\", т.к. он будет перекликаться с пунктом \"Сервис\" главного меню и группой \"Сервис\" в панели / меню функций

      \n

       

      \n

      3. Картинки разделов

      \n

       

      \n

      3.1. Названия разделов рекомендуется выводить в режиме \"Картинка и текст\"

      \n

       

      \n

      3.2. Картинки следует делать разными по начертанию и ведущим цветам для лучшей запоминаемости. Но при этом они должны быть нарисованы в одном стиле, с одинаковым направлением света. Картинки должны быть нарисованы во фронтальной плоскости проекции

      \n

       

      \n

      См. также:

      \n

      Панель разделов (8.2)

      \n

      Названия разделов (8.2)

      \n

      Картинки разделов (8.2)

      \n

      Подсказки для интерфейсных подсистем (8.2)

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "313", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Длина названия команды превышает 38 символов.", +"Description": "

      Навигация внутри раздела

      #std714

      Область применения: управляемое приложение.

      \n

      Навигация внутри конкретного раздела осуществляется с помощью \"Панели функций текущего раздела\" или области навигации и действий в составе \"Меню функций\"

      \n

       

      \n

      Панель функций текущего раздела

      \n

      \n

      Панель функций текущего раздела рекомендуется использовать в конфигурациях, содержащих небольшое количество команд в каждом разделе. В конфигурациях со сложной структурой и большим количеством команд эту панель рекомендуется скрывать.

      \n

       

      \n

      Область команд навигации и действий в составе \"Меню функций\"

      \n

      \n

      Область команд навигации и действий показывает все функциональные возможности раздела. В отличие от панели функций текущего раздела, команды здесь можно группировать.

      \n

       

      \n

      1. Состав команд

      \n

       

      \n

      1.1. В раздел рекомендуется помещать команды перехода к:

      \n

      ·          спискам и журналам документов

      \n

      ·          спискам \"первичных\" документов (данных), с которых начинаются бизнес-процессы

      \n

      ·          рабочим местам

      \n

      ·          специальным обработкам, похожим на обычные списки

      \n

      ·          отчетам

      \n

      При этом все эти команды должны решать задачу по конкретному участку работ или области деятельности.

      \n

       

      \n

      1.2. Второстепенные и подчиненные другим объекты можно не выносить в командный интерфейс.

      \n

      Чаще всего это справочники и регистры сведений, доступ к которым можно получить из документов или других объектов.

      \n

      Например:

      \n

      \n\n\n\n\n\n\n\n
      \n

      Справочники \"Контрагенты\", \"Договоры\" выносятся в командный интерфейс:

      \n

      Справочник \"Причины списания основного средства\" не выносится в командный интерфейс:

      \n

      - эти справочники открываются из разных документов, но они могут использоваться и без привязки к документам, например, для просмотра контактной информации по контрагенту или условий оплаты по договору

      \n

      - справочники могут содержать много элементов, может потребоваться работа с их списком. Например, поиск договоров по статусу или периоду, удаление дубликатов контрагентов

      \n

      - этот справочник можно открыть из одного специализированного документа \"Списание основного средства\"

      \n

      - элементов этого справочника мало и они редко изменяются, у пользователя нет необходимости просматривать список этих элементов в отрыве от контекста

      \n

       

      \n

      2. Названия команд

      \n

       

      \n

      2.1. Чтобы при стандартном разрешении экрана не возникало полос прокрутки, рекомендуется следить, чтобы названия команд не превышали 38 символов, а лучше – умещались в 30.

      \n

       

      \n

      3. Группировка команд

      \n

       

      \n

      3.1. Область команд включает в себя блок с командами навигации и блок с командами действий, но для пользователя все они выглядят одинаково. Поэтому при группировке следует объединять команды не по техническим признакам (вид объекта; действие, происходящее при выборе команды), а по тому, как их структурирует пользователь в своей работе.

      \n

       

      \n

      3.2. В одну группу рекомендуется включать не более 5-6 команд

      \n

       

      \n

      3.3. Не рекомендуется делать группы, содержащие всего одну команду.

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

       

      \n

      \n

       

      \n

       

      \n

      \n

       Запрещается делать группы, в которых выводится только одна \"важная\" команда.

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

       

      \n

      \n

       

      \n

      или

      \n

       

      \n

      \n

       

      \n

       

      \n

      \n

      \n

      3.4. Группам рекомендуется добавлять название. При этом оно не должно пересекаться с названиями системных групп (\"Создать\", \"Отчеты\", \"Сервис\", \"Важное\", \"См. также\"). Обязательно нужно добавлять заголовок для групп, состоящих из нескольких команд и содержащих только одну важную. 

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

       

      \n

      \n

       

      \n

       

      \n

       

      \n

      \n

      См. также:

      \n

      Панель навигации основного окна (8.2)

      \n

      Порядок и названия команд в ПН (8.2)

      \n

      Группа команд «Важное» в ПН (8.2)

      \n

      Группировка команд в ПН (8.2)

      \n

      Группа «См. также» в ПН (8.2)

      \n

      Команды, размещаемые в ПН (8.2)

      \n

      Панель действий (8.2)

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "316", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использование логического \"ИЛИ\" в секции \"ГДЕ\" запроса.", +"Description": "

      Эффективные условия запросов

      #std658

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Условия запросов должны быть написаны оптимально с точки зрения производительности, чтобы исключить существенное увеличение длительности выполнения запросов при увеличении объема данных в таблицах.

      \n

      Поля основного условия в секциях ГДЕ, ПО и виртуальных таблицах должны быть проиндексированы. Основное условие может быть уточнено дополнительным условием, но объединять их следует только по И.

      \n

      Важно понимать структуру индексов, которые получаются при индексировании полей и учитывать их при построении основного условия (см. Индексы таблиц базы данных, Несоответствие индексов и условий запроса). Например, при индексировании разных полей одного объекта метаданных создаются разные индексы, а не один в который помещаются все проиндексированные поля и использоваться основным условием будет только один из них.

      \n

      Основное условие – это то, что позволяет ограничить объем выборки больше других условий и его составляющие объединены по И.

      \n

      Дополнительное условие – это то, что объединено с основным условием по И и его составляющие могут быть любой сложности (НЕ, <>, +, -, /, *, функции и т.п.).

      \n

      Основное условие должно содержать только такие операции, которые позволяют выполнять поиск по индексу:

      \n
        \n
      • для первого и всех используемых полей индекса, кроме последнего, только = и И; \n
      • для последнего или единственного используемого поля индекса допустимо использовать =, >, <, >=, <=, ПОДОБНО, МЕЖДУ, В, ИЛИ (приводимое к В); \n
      • нельзя использовать арифметические операции, функции, отрицания и неравенства.
      \n

      Для условий в ГДЕ или в виртуальной таблице следует индексировать поля в основной таблице, из которой выполняется выборка.

      \n

      Для условий в ПО ЛЕВОГО соединения следует индексировать поля в правой таблице.

      \n

      Для условий в ПО ВНУТРЕННЕГО соединения следует индексировать поля в таблице с большим количеством записей.

      \n

      Основное условие желательно строить таким образом, чтобы оно использовало индексы, которые автоматически создает платформа.

      \n

      1.1. Описанные выше требования допустимо не соблюдать, если в таблицах, из которых выполняется выборка, или с которыми выполняется соединение, всегда будет мало данных (менее 1000 записей) или запросы с такими условиями выполняются очень редко.

      \n

      1.2. Если записей в таблице много и выполнить указанные выше требования невозможно, то можно попробовать:

      \n
        \n
      • преобразовать условия (см. п. 3, п. 4); \n
      • добавить в таблицу заранее вычисляемые индексированные поля, которые заполняются при записи в нее и используются вместо сложного условия; \n
      • если указанные выше рекомендации не помогли, то следует пересмотреть архитектуру решения так, чтобы можно было выполнить эти условия.
      \n

      2. Оператор ИЛИ

      \n

      2.1. В основном условии оператор ИЛИ можно использовать только для последнего из используемых или единственного поля индекса, когда оператор ИЛИ можно заменить на оператор В.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле = &Значение1
          ИЛИ Таблица.Поле = &Значение2

      \n

      т.к. можно переписать при помощи оператора В (специально переписывать не нужно, можно оставить, как есть):

      \n

      ГДЕ
          Таблица.Поле В (&Значения)

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1
          ИЛИ Таблица.Поле2 = &Значение2

      \n

      нельзя переписать при помощи \"В\", но можно переписать при помощи \"ОБЪЕДИНИТЬ ВСЕ\" (каждое поле Поле1 и Поле2 должны быть проиндексированы):

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1

      ОБЪЕДИНИТЬ ВСЕ

      ГДЕ
          Таблица.Поле2 = &Значение1

      \n

      Примечание: заменить ИЛИ на ОБЪЕДИНИТЬ ВСЕ можно не всегда, убедитесь, что результат будет действительно тем же, что и при ИЛИ, перед тем, как применять.

      \n

      2.2. В дополнительном условии оператор ИЛИ можно использовать без ограничений.

      \n

      ПРАВИЛЬНО 1:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно использовать ИЛИ)
          (Таблица.Поле2 = &Значение2 ИЛИ Таблица.Поле3 = &Значение3)

      \n

      ПРАВИЛЬНО 2:

      \n

      ГДЕ
          (Таблица.Поле1 = &Значение1 ИЛИ Таблица.Поле1 = &Значение2)
          И
          (Таблица.Поле2 = &Значение3 ИЛИ Таблица.Поле2 = &Значение4)

      \n

      т.к. можно переписать при помощи В (специально переписывать не нужно, можно оставить, как есть):

      \n

      ГДЕ
          Таблица.Поле1 В (&Значения1)   // Основное условие
          И Таблица.Поле2 В (&Значения2) // Дополнительное условие (или наоборот)

      \n

      3. Оператор ПОДОБНО

      \n

      В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор ПОДОБНО. Функции работы со строками, в некоторых случаях, можно привести к оператору ПОДОБНО и использовать его в основном условии.

      \n

      НЕПРАВИЛЬНО 1:

      \n

      ГДЕ
          ПОДСТРОКА(Таблица.Поле, 1, 6) = \"строка\"

      \n

      ПРАВИЛЬНО 1:

      \n

      ГДЕ
          Таблица.Поле ПОДОБНО \"строка%\"

      \n

      НЕПРАВИЛЬНО 2:

      \n

      ГДЕ
          ПОДСТРОКА(Таблица.Поле, 3, 6) = \"строка\"

      \n

      НЕПРАВИЛЬНО 2:

      \n

      ГДЕ
          Таблица.Поле ПОДОБНО \"__строка%\" // Литерал не должен начинаться с символов \"_\" или \"%\"

      \n

      ПРАВИЛЬНО 2:

      \n

      Добавить новое вычисляемое при записи в таблицу поле, которое будет содержать фрагмент ПОДСТРОКА(Таблица.Поле, 3, 6). Проиндексировать это поле и искать по следующему условию:

      \n

      ГДЕ
          Таблица.ВычисляемоеПоле ПОДОБНО \"строка%\"

      \n

      4. Оператор МЕЖДУ

      \n

      В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор МЕЖДУ. Функции работы с датой, в некоторых случаях, можно привести к оператору МЕЖДУ и использовать его в основном условии.

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          МЕСЯЦ(Таблица.Поле) = 1

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле МЕЖДУ &ДатаНачалаМесяца И &ДатаКонцаМесяца

      \n

      Например, ДатаНачалаМесяца=01.01.2016, ДатаКонцаМесяца=31.01.2016 23:59:59

      \n

      5. Выражение ВЫБОР

      \n

      Выражение ВЫБОР можно использовать только в дополнительных условиях.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно использовать ВЫБОР)
          ВЫБОР
              КОГДА Таблица.Поле2 = &Значение2
                  ТОГДА Таблица.Поле3 = &Значение3
              ИНАЧЕ Таблица.Поле4 = &Значение4
          КОНЕЦ

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          ВЫБОР // Основное условие (поиск по индексу использоваться не будет)
              КОГДА Таблица.Поле2 = &Значение2
                  ТОГДА Таблица.Поле3 = &Значение3
              ИНАЧЕ Таблица.Поле4 = &Значение4
          КОНЕЦ

      \n

      6. Арифметические операции

      \n

      Арифметические операции над полями можно выполнять только в дополнительных условиях.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно выполнять арифметические операции)
          Таблица.Поле2 - 1 > 0

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 - 1 > 0 // Основное условие (поиск по индексу невозможен)

      \n

      7. Если в конфигурации описано несколько ролей с разным ограничением доступа на уровне записей (RLS), то не следует назначать одному пользователю более одной такой роли. Если один пользователь будет включен, например, в две роли с RLS - бухгалтер и кадровик, то при выполнении всех его запросов к их условиям будут добавляться условия обоих RLS с использованием логического ИЛИ. Таким образом, даже если в исходном запросе нет условия ИЛИ, оно появится там после добавления условий RLS. Такой запрос так же может выполняться неоптимально - медленно и с избыточными блокировками.

      \n

      Вместо этого следует:

      \n
        \n
      • \n
        Пересмотреть состав ролей таким образом, чтобы к одному объекту метаданных давала доступ только одна роль (на чтение, запись и т.п.);
        \n
      • \n
        При необходимости разработки нескольких ролей, предоставляющих доступ к одному объекту метаданных, задавать в них одинаковые условия RLS. В этом случае к тексту запроса будет добавлено только одно условие, без объединения по ИЛИ;
        \n
      • \n
        Либо если это допустимо с точки зрения прикладной области, создать \"смешанную\" роль - \"бухгалтер-кадровик\" и прописать ее RLS таким образом, чтобы избежать использования ИЛИ в условии, а пользователя включить в эту одну роль.
      \n

      См. также

      \n
    5. Типичные причины неоптимальной работы запросов и методы оптимизации (статья на ИТС) \n
    6. Стандартные роли \n
    7. Настройка ролей и прав доступа
    8. ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "317", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использование логического \"ИЛИ\" в секции \"ПО\" запроса.", +"Description": "

      Эффективные условия запросов

      #std658

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Условия запросов должны быть написаны оптимально с точки зрения производительности, чтобы исключить существенное увеличение длительности выполнения запросов при увеличении объема данных в таблицах.

      \n

      Поля основного условия в секциях ГДЕ, ПО и виртуальных таблицах должны быть проиндексированы. Основное условие может быть уточнено дополнительным условием, но объединять их следует только по И.

      \n

      Важно понимать структуру индексов, которые получаются при индексировании полей и учитывать их при построении основного условия (см. Индексы таблиц базы данных, Несоответствие индексов и условий запроса). Например, при индексировании разных полей одного объекта метаданных создаются разные индексы, а не один в который помещаются все проиндексированные поля и использоваться основным условием будет только один из них.

      \n

      Основное условие – это то, что позволяет ограничить объем выборки больше других условий и его составляющие объединены по И.

      \n

      Дополнительное условие – это то, что объединено с основным условием по И и его составляющие могут быть любой сложности (НЕ, <>, +, -, /, *, функции и т.п.).

      \n

      Основное условие должно содержать только такие операции, которые позволяют выполнять поиск по индексу:

      \n
        \n
      • для первого и всех используемых полей индекса, кроме последнего, только = и И; \n
      • для последнего или единственного используемого поля индекса допустимо использовать =, >, <, >=, <=, ПОДОБНО, МЕЖДУ, В, ИЛИ (приводимое к В); \n
      • нельзя использовать арифметические операции, функции, отрицания и неравенства.
      \n

      Для условий в ГДЕ или в виртуальной таблице следует индексировать поля в основной таблице, из которой выполняется выборка.

      \n

      Для условий в ПО ЛЕВОГО соединения следует индексировать поля в правой таблице.

      \n

      Для условий в ПО ВНУТРЕННЕГО соединения следует индексировать поля в таблице с большим количеством записей.

      \n

      Основное условие желательно строить таким образом, чтобы оно использовало индексы, которые автоматически создает платформа.

      \n

      1.1. Описанные выше требования допустимо не соблюдать, если в таблицах, из которых выполняется выборка, или с которыми выполняется соединение, всегда будет мало данных (менее 1000 записей) или запросы с такими условиями выполняются очень редко.

      \n

      1.2. Если записей в таблице много и выполнить указанные выше требования невозможно, то можно попробовать:

      \n
        \n
      • преобразовать условия (см. п. 3, п. 4); \n
      • добавить в таблицу заранее вычисляемые индексированные поля, которые заполняются при записи в нее и используются вместо сложного условия; \n
      • если указанные выше рекомендации не помогли, то следует пересмотреть архитектуру решения так, чтобы можно было выполнить эти условия.
      \n

      2. Оператор ИЛИ

      \n

      2.1. В основном условии оператор ИЛИ можно использовать только для последнего из используемых или единственного поля индекса, когда оператор ИЛИ можно заменить на оператор В.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле = &Значение1
          ИЛИ Таблица.Поле = &Значение2

      \n

      т.к. можно переписать при помощи оператора В (специально переписывать не нужно, можно оставить, как есть):

      \n

      ГДЕ
          Таблица.Поле В (&Значения)

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1
          ИЛИ Таблица.Поле2 = &Значение2

      \n

      нельзя переписать при помощи \"В\", но можно переписать при помощи \"ОБЪЕДИНИТЬ ВСЕ\" (каждое поле Поле1 и Поле2 должны быть проиндексированы):

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1

      ОБЪЕДИНИТЬ ВСЕ

      ГДЕ
          Таблица.Поле2 = &Значение1

      \n

      Примечание: заменить ИЛИ на ОБЪЕДИНИТЬ ВСЕ можно не всегда, убедитесь, что результат будет действительно тем же, что и при ИЛИ, перед тем, как применять.

      \n

      2.2. В дополнительном условии оператор ИЛИ можно использовать без ограничений.

      \n

      ПРАВИЛЬНО 1:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно использовать ИЛИ)
          (Таблица.Поле2 = &Значение2 ИЛИ Таблица.Поле3 = &Значение3)

      \n

      ПРАВИЛЬНО 2:

      \n

      ГДЕ
          (Таблица.Поле1 = &Значение1 ИЛИ Таблица.Поле1 = &Значение2)
          И
          (Таблица.Поле2 = &Значение3 ИЛИ Таблица.Поле2 = &Значение4)

      \n

      т.к. можно переписать при помощи В (специально переписывать не нужно, можно оставить, как есть):

      \n

      ГДЕ
          Таблица.Поле1 В (&Значения1)   // Основное условие
          И Таблица.Поле2 В (&Значения2) // Дополнительное условие (или наоборот)

      \n

      3. Оператор ПОДОБНО

      \n

      В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор ПОДОБНО. Функции работы со строками, в некоторых случаях, можно привести к оператору ПОДОБНО и использовать его в основном условии.

      \n

      НЕПРАВИЛЬНО 1:

      \n

      ГДЕ
          ПОДСТРОКА(Таблица.Поле, 1, 6) = \"строка\"

      \n

      ПРАВИЛЬНО 1:

      \n

      ГДЕ
          Таблица.Поле ПОДОБНО \"строка%\"

      \n

      НЕПРАВИЛЬНО 2:

      \n

      ГДЕ
          ПОДСТРОКА(Таблица.Поле, 3, 6) = \"строка\"

      \n

      НЕПРАВИЛЬНО 2:

      \n

      ГДЕ
          Таблица.Поле ПОДОБНО \"__строка%\" // Литерал не должен начинаться с символов \"_\" или \"%\"

      \n

      ПРАВИЛЬНО 2:

      \n

      Добавить новое вычисляемое при записи в таблицу поле, которое будет содержать фрагмент ПОДСТРОКА(Таблица.Поле, 3, 6). Проиндексировать это поле и искать по следующему условию:

      \n

      ГДЕ
          Таблица.ВычисляемоеПоле ПОДОБНО \"строка%\"

      \n

      4. Оператор МЕЖДУ

      \n

      В основном условии для последнего из используемых или единственного поля индекса можно использовать оператор МЕЖДУ. Функции работы с датой, в некоторых случаях, можно привести к оператору МЕЖДУ и использовать его в основном условии.

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          МЕСЯЦ(Таблица.Поле) = 1

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле МЕЖДУ &ДатаНачалаМесяца И &ДатаКонцаМесяца

      \n

      Например, ДатаНачалаМесяца=01.01.2016, ДатаКонцаМесяца=31.01.2016 23:59:59

      \n

      5. Выражение ВЫБОР

      \n

      Выражение ВЫБОР можно использовать только в дополнительных условиях.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно использовать ВЫБОР)
          ВЫБОР
              КОГДА Таблица.Поле2 = &Значение2
                  ТОГДА Таблица.Поле3 = &Значение3
              ИНАЧЕ Таблица.Поле4 = &Значение4
          КОНЕЦ

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          ВЫБОР // Основное условие (поиск по индексу использоваться не будет)
              КОГДА Таблица.Поле2 = &Значение2
                  ТОГДА Таблица.Поле3 = &Значение3
              ИНАЧЕ Таблица.Поле4 = &Значение4
          КОНЕЦ

      \n

      6. Арифметические операции

      \n

      Арифметические операции над полями можно выполнять только в дополнительных условиях.

      \n

      ПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 = &Значение1 // Основное условие (использует индекс)
          И // Дополнительное условие (можно выполнять арифметические операции)
          Таблица.Поле2 - 1 > 0

      \n

      НЕПРАВИЛЬНО:

      \n

      ГДЕ
          Таблица.Поле1 - 1 > 0 // Основное условие (поиск по индексу невозможен)

      \n

      7. Если в конфигурации описано несколько ролей с разным ограничением доступа на уровне записей (RLS), то не следует назначать одному пользователю более одной такой роли. Если один пользователь будет включен, например, в две роли с RLS - бухгалтер и кадровик, то при выполнении всех его запросов к их условиям будут добавляться условия обоих RLS с использованием логического ИЛИ. Таким образом, даже если в исходном запросе нет условия ИЛИ, оно появится там после добавления условий RLS. Такой запрос так же может выполняться неоптимально - медленно и с избыточными блокировками.

      \n

      Вместо этого следует:

      \n
        \n
      • \n
        Пересмотреть состав ролей таким образом, чтобы к одному объекту метаданных давала доступ только одна роль (на чтение, запись и т.п.);
        \n
      • \n
        При необходимости разработки нескольких ролей, предоставляющих доступ к одному объекту метаданных, задавать в них одинаковые условия RLS. В этом случае к тексту запроса будет добавлено только одно условие, без объединения по ИЛИ;
        \n
      • \n
        Либо если это допустимо с точки зрения прикладной области, создать \"смешанную\" роль - \"бухгалтер-кадровик\" и прописать ее RLS таким образом, чтобы избежать использования ИЛИ в условии, а пользователя включить в эту одну роль.
      \n

      См. также

      \n
    9. Типичные причины неоптимальной работы запросов и методы оптимизации (статья на ИТС) \n
    10. Стандартные роли \n
    11. Настройка ролей и прав доступа
    12. ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "319", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Периодичность выполнения регламентного задания меньше одной минуты.", +"Description": "

      Настройка расписания регламентных заданий

      #std402

      Область применения: управляемое приложение, обычное приложение.

      \n

      При разработке регламентных заданий необходимо выбирать время и интервал запуска, исходя из прикладного назначения регламентных заданий, а также руководствуясь соображением, что частое выполнение регламентных заданий может негативно влиять на производительность сервера приложений 1С:Предприятие:

      \n
        \n
      • \n
        регламентное задание не должно выполняться чаще, чем это нужно с прикладной точки зрения;
        \n
      • \n
        с точки зрения оптимальной загрузки сервера приложений для большинства регламентных заданий нормальным является интервал выполнения заданий в 1 день; 
        \n
      • \n
        исключения могут составлять случаи, когда критичным является частое выполнение заданий с прикладной точки зрения, например, для поддержания актуальности данных за короткий период;
        \n
      • \n
        ни в каких случаях не следует задавать периодичность выполнения регламентных заданий меньше одной минуты;
        \n
      • \n
        периодичность выполнения частых (с периодичностью менее одного дня) регламентных заданий должна быть сбалансирована со временем выполнения задания: например, если типичное время выполнения 20 секунд, то периодичность раз в минуту, скорее всего, избыточна;
        \n
      • \n
        выполнение ресурсоемких регламентных операций необходимо по возможности переносить на время минимальной загрузки сервера приложений 1С:Предприятие. Например, в нерабочее время или на выходные дни;
        \n
      • \n
        несколько различных ресурсоемких регламентных заданий лучше \"разносить\" по времени, исходя из ожидаемого времени их выполнения.
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "320", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "НСтр() в выражении параметра макета. Значение параметра нужно задавать с помощью НСтр() не в колонке \"Выражение\", а в модуле отчета.", +"Description": "

      Запросы, динамические списки и отчеты на СКД: требования по локализации

      #std762

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

      \n

      Неправильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
      \n

      Также неправильно:

      ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      Правильно:

      ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
      \n

      2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

      \n

      а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

      \n

      б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

      \n

      Неправильно:

      ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
      \n

      Правильно:

      ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
      \n

      в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

      \n

      Неправильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
      \n

      Правильно:

      Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
      \n

      3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

      \n

      Неправильно:

      \n

      Правильно:

      \n

      В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "321", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Термин \"1C:Предприятие\" ошибочно задан с латинской \"C\".", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "323", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в заголовке команды формы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "324", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Орфографическая ошибка в подсказке команды формы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "325", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: отсутствует вызов \"НачатьТранзакцию()\", хотя вызываются \"ЗафиксироватьТранзакцию()\"/\"ОтменитьТранзакцию()\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "326", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: для вызова \"НачатьТранзакцию()\" отсутствует парный вызов \"ЗафиксироватьТранзакцию()\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "327", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: для вызова \"НачатьТранзакцию()\" отсутствует парный вызов \"ОтменитьТранзакцию()\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "328", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: не найден оператор \"Попытка\" после вызова \"НачатьТранзакцию()\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "329", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: вызов \"ЗафиксироватьТранзакцию()\" находится вне конструкции \"Попытка... Исключение\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "330", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: между \"ЗафиксироватьТранзакцию()\" и \"Исключение\" есть исполняемый код, который может вызвать исключение.", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "331", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: между \"НачатьТранзакцию()\" и \"Попытка\" есть исполняемый код.", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "332", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: вызов \"ОтменитьТранзакцию()\" отсутствует в конструкции \"Исключение... КонецПопытки\".", +"Description": "

      Транзакции: правила использования

      #std783

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

      \n

      1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

      \n\n

      Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

      \n

      1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

      \n

      1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

      \n

      Правильно

      \n

      Процедура ЗаписатьДанныеВИБ()

      \n

          НачатьТранзакцию();

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
              ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      Неправильно

      \n

      Процедура ЗаписатьДанныеВИБ()
       
          НачатьТранзакцию();
          ЗаписатьДокумент();

      \n

      КонецПроцедуры;

      \n

      Процедура ЗаписатьДокумент()

      \n

          Попытка
              ... // чтение или запись данных
              ДокументОбъект.Записать()
              ЗафиксироватьТранзакцию();
          Исключение
              ОтменитьТранзакцию();
          ... // дополнительные действия по обработке исключения
          КонецПопытки;

      \n

      КонецПроцедуры

      \n

      1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

      \n
        \n
      • \n
        метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
        \n
      • \n
        все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
        \n
      • \n
        метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
        \n
      • \n
        необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
        \n
      • \n
        рекомендуется в блоке Исключение делать запись в журнал регистрации;
        \n
      • \n
        при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
      \n

      Пример

      \n

      НачатьТранзакцию();
      Попытка
          БлокировкаДанных = Новый БлокировкаДанных;
          ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
          ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
          ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
          БлокировкаДанных.Заблокировать();

      \n

          ... // чтение или запись данных

          ДокументОбъект.Записать();

      \n

          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();

      \n

          ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
              УровеньЖурналаРегистрации.Ошибка,
              ,
              ,
              ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

      \n

          ВызватьИсключение; // есть внешняя транзакция

      \n

      КонецПопытки;

      \n

      1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

      \n

      1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

      \n

      Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

      \n

      При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

      \n

      Правильно

      \n

      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
      Исключение
          ... // действия по обработке исключения
      КонецПопытки;

      \n

      Неправильно

      \n

      НачатьТранзакцию();
      Попытка
          ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
          ... // действия по заполнению объекта
          ДокументОбъект.Записать();
          ЗафиксироватьТранзакцию();
      Исключение
          ОтменитьТранзакцию();
      КонецПопытки;

      \n

      1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

      \n

      1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

      \n

      Пример

      \n

      Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

      \n

      1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

      \n

      2. Ограничение на длину транзакции.

      \n

      2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

      \n

      Пример

      \n

      При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

      \n

      2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

      \n

      2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

      \n

      2.2. Следует избегать транзакций, которые выполняются длительное время.

      \n

      Пример

      \n

      Неправильно

      \n

      Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

      \n

      Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

      \n

      Правильно

      \n

      Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

      \n

      См. также Особенности использования транзакций при обмене данными

      \n

      2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

      \n
        \n
      • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
      • блокировки, установленные в транзакции, остаются до конца транзакции; \n
      • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
      • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
      \n

      Все это в целом может снижать эффективность использования ресурсов.

      \n

      2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

      \n

      Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

      \n
        \n
      • \n
        возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
        \n
      • \n
        если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
        \n
      • \n
        так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
      \n

      2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

      \n
        \n
      • \n
        сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
        \n
      • \n
        если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
        \n
      • \n
        проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
        \n
      • \n
        запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
        \n
      • \n
        запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "334", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Функция НСтр() использована для локализации внутренних идентификаторов.", +"Description": "

      Строковые константные выражения в коде: требования по локализации

      #std764

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Не локализуются строковые константы с внутренними идентификаторами, которые не выводятся пользователям. К ним не следует применять функцию НСтр. При этом, такие строковые идентификаторы должны именоваться по правилам именования идентификаторов переменных встроенного языка.

      \n

      Например:

      Возврат \"ОперацияВыполненаУспешно\";\nОповестить(\"ЗаписьФайл\", Новый Структура(\"Событие\", \"ВерсияСохранена\"), ФайлСсылка);
      \n

      Неправильно:

      Если Статус = \"Отгрузка клиентам\" Тогда ...
      \n

      Правильно:

      Если Статус = \"ОтгрузкаКлиентам\" Тогда ...
      \n

      Это требование распространяется и на использование идентификаторов в текстах запросов и в выражениях СКД.

      \n

      При использовании в коде строковых констант можно и даже предпочтительно применять функции, возвращающие эти строковые константы, такой подход упрощает отладку и рефакторинг кода.

      \n

      Правильно:

      РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(...);\nЕсли РезультатЗагрузки = РезультатЗагрузкиУспешно() Тогда \n...\nИначеЕсли ...\n\nФункция РезультатЗагрузкиУспешно()\n  Возврат \"Успешно\"; \nКонецФункции
      \n

      Это устраняет неоднозначность, когда идентификатор визуально выглядит в коде как строка, выводимая пользователю, но без необходимого НСтр.

      \n

      2. В алгоритмах программы не следует использовать представления объектов и типов. Строковые представления предназначены только для вывода пользователю, они могут различаться в зависимости от текущего языка программы. Поэтому их использование приводит к ошибкам при локализации конфигурации, а также при интеграции с системами на других языках. Частные случаи некорректного использования представлений объектов и типов в коде.

      \n

      2.1. Для получения предопределенного значения на клиенте следует указывать его строковое имя, как оно указано в конфигураторе.

      \n

      Например, неправильно:

      Если Строка(ЮрФизЛицо) = \"Юридическое лицо\" Тогда
      \n

      правильно

      Если ЮрФизЛицо = ПредопределенноеЗначение(\"Перечисление.ЮридическоеФизическоеЛицо.ЮридическоеЛицо\") Тогда
      \n

      Подробнее см. раздел Работа с предопределенными значениями в документации к платформе 1С:Предприятие (на ИТС).

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "335", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Обнаружена нелокализованная дата.", +"Description": "

      Форматирование даты, числа, Булево: требования по локализации

      #std763

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При использовании функции Формат в некоторых случаях следует использовать функцию НСтр при создании форматной строки (формат представления или редактирования дат, Булево значения и т.п.) . При этом форматная строка, задаваемая в свойствах метаданных (форм), подлежит локализации всегда, также, как синоним.

      \n

      1.1. Форматирование дат

      \n

      для вывода дат следует учитывать, что в различных странах приняты различные порядок следования и разделители для составных частей даты.

      \n

      Например, одна и та же дата: 20.12.2012 – для России, 12/20/2012 – для США.

      \n

      Поэтому вместо явного задания формата даты рекомендуется использовать локальный формат даты (ДЛФ).

      \n

      В случаях, когда использовать локальный формат даты не получатся, и требуется задать произвольный формат (ДФ) или указать представление пустой даты (ДП) нужно применять функцию НСтр к форматной строке, чтобы при локализации оставалась возможность переопределить выводимый формат:

      \n

      Неправильно:

      Формат(ДатаУтверждения, \"ДФ=дд.ММ.гггг\");\nФормат(ДатаУтверждения, \"ДФ=ММММ гггг\") + \" г.\";\n
      \n

      Правильно:

      Формат(ДатаУтверждения, \"ДЛФ=ДД\");\nФормат(ДатаУтверждения, НСтр(\"ru='ДФ=ММММ гггг \"\"г.\"\"'\");\n
      \n

      1.2. Форматирование числа

      \n

      Следует применять функцию НСтр к форматной строке в случае, когда
      • для числа задается нечисловое представление нулевого значения (ЧН) ;
      • указан шаблон форматирования числа (ЧФ);
      • переопределяется разделитель дробной части (ЧРД).

      \n

      Неправильно:

      Предупреждение(Формат(100, \"ЧН=Отсутствует\"));\nПредупреждение(Формат(100, \"ЧФ=\"\"$Ч' / Час'\"\"\"));\n
      \n

      Правильно:

      Предупреждение(Формат(100, НСтр(\"ru = 'ЧН=Отсутствует'\")));\nПредупреждение(Формат(100, НСтр(\"ru = 'ЧФ=\"\"$Ч'' / Час''\"\"'\"))); // \"$100 / Час\"\n
      \n

      1.3. Форматирование Булево

      \n

      Для вывода Булево значения пользователю всегда применяйте функцию НСтр к форматной строке.

      \n

      Неправильно:

      Предупреждение(Формат(Истина, \"БЛ=Нет; БИ=Да\"));\n
      \n

      Правильно:

      Предупреждение(Формат(Истина, НСтр(\"ru='БЛ=Нет; БИ=Да'\")));\n
      \n

      1.4. Не следует переопределять поведение отображения локализации данных по умолчанию – формат отображения операционной системы. При использовании функции Формат следует избегать использовать параметр «L=».

      \n

      2. При задании формата в полях ввода в формах и полях отчетов на базе СКД также рекомендуется локальный формат даты. Использовать другие форматы допустимо, если по сути решаемой задачи локальный формат не подходит – тогда форматная строка будет переводиться при переводе конфигурации.

      \n

      3. При переопределении стандартных представлений полей в отчетах на базе СКД следует придерживаться тех же правил, что и в коде модулей. Например, неправильно:

      \n

      \"N \" + ВОтветНаНомер + \" от \" + Формат(ВОтветНаДата, \"ДФ=dd.MM.yyyy\")

      \n

      правильное выражение, по которому вычисляется представление поля:

      СтрШаблон(\n  НСтр(\"ru = 'N%1 от %2'\"),\n  ВОтветНаНомер,\n  Формат(ВОтветНаДата, \"ДЛФ=D\"))\n
      \n

      4. В случае, когда требуется передача значения в машиночитаемом виде, вне зависимости от информационной системы и настроек локализации, применяемых в ней, вместо локализации значения следует выполнить сериализацию. Локализацию дат нужно использовать всегда, когда это возможно. В тех случаях, когда это технически нецелесообразно, допускается отказываться от локализации. Например, при генерации файла формата XML, поддерживаемого банк-клиентом системы, специфичной для России.

      \n

      В общем случае для сериализации рекомендуется использовать метод XMLСтрока.

      \n

      Для десериализации XMLЗначение. Или метод ПривестиЗначение объекта ОписаниеТипов.

      \n

      4.1. Сериализация дат

      \n

      При разработке собственных форматов передачи данных между различными системами рекомендуется сериализовать дату в формате ISO: \"ГГГГ-ММ-ДДTЧЧ:ММ:ССZ\", например \"2009-02-15T00:00:00Z\" (соответствует типу dateTime схемы XML см. http://www.w3.org/TR/xmlschema-2/#dateTime).

      \n

      Неправильно:

      \n

      Строка = Формат(Дата, \"ДФ=гггг-ММ-ддTЧЧ:мм:сс\"); // Сериализация

      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Дата); // Сериализация\n// Или\nСтрока = ЗаписатьДатуJSON(Дата, ФорматДатыJSON.ISO); // Сериализация\nОписаниеТипа = Новый ОписаниеТипов(\"Дата\");\nДата = ОписаниеТипа.ПривестиЗначение(Строка);
      // Десериализация\nДата = XMLЗначение(Тип(\"Дата\"), Строка); \n// Или\nДата = ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO);\n
      \n

      4.2. Сериализация числа

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Число);\n// Или\nСтрока = Формат(Число);\n
      \n

      Правильно:

      \n

      Строка = XMLСтрока(Число); // Сериализация
      Число = XMLЗначение(Тип(\"Число\"), Строка); // Десериализация

      \n

      4.3. Сериализация Булево

      \n

      Неправильно:

      // Сериализация\nСтрока = Строка(Булево);\n// Или\nСтрока = Формат(Булево);\n// Или\nСтрока = Формат(Булево, \"БЛ=off; БИ=on\");
      \n

      Правильно:

      // Сериализация\nСтрока = XMLСтрока(Булево);\n// Или\nБулево = XMLЗначение(Тип(\"Булево \"), Строка);\n// Или\nСтрока = ?(Булево, \"on\", \"off\");\n
      \n


      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "336", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использован метод \"РольДоступна()\".", +"Description": "

      Проверка прав доступа

      #std737

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

      \n
        \n
      • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
      • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
      \n

      Эти меры позволяют:

      \n
        \n
      • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
      • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
      • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
      \n

      2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

      \n

      3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
      Например, неправильно:

      \n

      Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
      Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

      \n

      правильно:

      \n

      Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
      Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

      \n

      Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

      \n

      4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
      Например, без использования БСП:

      \n

      Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

      \n

      Либо аналогичная проверка с использованием БСП:

      \n

      Если Пользователи.РолиДоступны(...) Тогда ...

      \n

      См. также

      \n\n\n\n

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "339", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Чтение пароля из базы данных в реквизит формы может быть небезопасной.", +"Description": "

      Безопасное хранение паролей

      #std740

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При разработке подсистем, взаимодействующих с различными внешними ресурсами (электронной почтой, веб-сервисами, FTP-ресурсами и т.п.) возникает необходимость запрашивать и передавать данные аутентификации к этим ресурсам: логин и пароль.

      \n

      2. Для сведения к минимуму возможности перехвата пароля злоумышленниками не следует хранить пароли и другую конфиденциальную информацию в информационной базе. При этом минимальный уровень защищенности – в файловых информационных базах, в которых файл базы может быть скопирован целиком любым пользователем информационной базы. В клиент-серверной информационной базе доступ к базе данных, как правило, имеется только у администраторов СУБД.

      \n

      Таким образом, следует запрашивать логин и пароль у пользователя и передавать их сразу, не сохраняя в информационной базе.

      \n

      3. В ряде случаев такая схема работы доставляет объективные неудобства или принципиально невозможна:

      \n
        \n
      • интерактивный запрос логина и пароля на каждую операцию может создавать значительный дискомфорт от работы, а временного сохранения на стороне клиента недостаточно; \n
      • взаимодействие с различными внешними ресурсами должно выполняться на сервере, не зависимо от интенсивности работы пользователей с программой.
      \n

      В таких случаях допустимо организовать хранение паролей и другой конфиденциальной информации в информационной базе, предупредив пользователей о последствиях. Следует помнить, что подобное хранение паролей не решает всех проблем безопасности, а лишь усложняет задачу для злоумышленника.

      \n

      3.1. При этом не следует хранить пароли и другую конфиденциальную информацию в реквизитах тех же объектов метаданных, с которыми ведется повседневная работа. Для хранения такой информации следует использовать отдельный объект метаданных (например, регистр сведений), организовав к нему безопасный доступ на уровне системы прав доступа 1С:Предприятия.

      \n

      3.2. При использовании Библиотеки стандартных подсистем (БСП) следует использовать безопасное хранилище паролей, которое решает ряд задач:

      \n
        \n
      • Имея доступ к объекту метаданных, пользователь может прочитать содержимое реквизита с паролем, что невозможно при использовании безопасного хранилища. Для исключения случаев несанкционированного доступа к безопасному хранилищу получение и запись данных (паролей) возможна только в привилегированном режиме. \n
      • Данные в безопасном хранилище хранятся в закрытом виде и тем самым исключаются случаи непредумышленной «засветки» паролей. \n
      • Безопасное хранилище исключено из планов обмена, что предотвращает утечку паролей из информационной базы при обмене данными.
      \n

      Для работы с безопасным хранилищем паролей предназначены процедуры и функции общего модуля ОбщегоНазначения: ЗаписатьДанныеВБезопасноеХранилищеПрочитатьДанныеИзБезопасногоХранилища и УдалитьДанныеИзБезопасногоХранилища. Подробнее см. комментарии к этим функциям в БСП и раздел «3.4. Базовая функциональность - Использование при разработке конфигурации - Безопасное хранилище паролей» документации БСП.

      \n

      3.3. Не следует хранить пароли в реквизитах формы, их следует извлекать только на стороне сервера и непосредственно перед их использованием. В противном случае, при открытии формы с маскированным вводом (или просмотром) пароля, пароль передается с  сервера на клиент в открытом виде, что делает возможным его перехват. Установка привилегированного режима производится непосредственно перед вызовом функций, а не внутри них, что бы исключить получение или запись любых паролей в сеансе с любыми правами. Безопасность вызова должен обеспечивать вызывающий код, который обращается к конкретным паролям.

      \n

      Для маскировки пароля на форме в обработчике событии формы ПриСозданииНаСервере необходимо разместить следующий код:

      \n

       УстановитьПривилегированныйРежим(Истина);
       Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Объект.Ссылка, \"Пароль, ПарольSMTP\"); // Пароль, ПарольSMTP – ключи соответствия данных в безопасном хранилище
       УстановитьПривилегированныйРежим(Ложь);

      \n

       Пароль = ?(ЗначениеЗаполнено(Пароли.Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       ПарольSMTP = ?(ЗначениеЗаполнено(Пароли.ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");

      \n

      В обработчике события формы ПриЗаписиНаСервере:

      \n

       Если ПарольИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
        УстановитьПривилегированныйРежим(Ложь);
        Пароль = ?(ЗначениеЗаполнено(Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;
       
       Если ПарольSMTPИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ПарольSMTP, \"ПарольSMTP\");
        УстановитьПривилегированныйРежим(Ложь);
        ПарольSMTP = ?(ЗначениеЗаполнено(ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;

      \n

      где Пароль и ПарольSMTP - реквизиты формы. Если пароль ранее был сохранен в программе, то следует присвоить соответствующему реквизиту уникальный идентификатор формы, эмулирующий наличие пароля. При записи объекта в форме, если был введен новый пароль, то записываем его в объект, а реквизит формы вновь затираем уникальным идентификатором.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "340", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Запись пароля в базу данных из реквизита формы может быть небезопасной.", +"Description": "

      Безопасное хранение паролей

      #std740

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При разработке подсистем, взаимодействующих с различными внешними ресурсами (электронной почтой, веб-сервисами, FTP-ресурсами и т.п.) возникает необходимость запрашивать и передавать данные аутентификации к этим ресурсам: логин и пароль.

      \n

      2. Для сведения к минимуму возможности перехвата пароля злоумышленниками не следует хранить пароли и другую конфиденциальную информацию в информационной базе. При этом минимальный уровень защищенности – в файловых информационных базах, в которых файл базы может быть скопирован целиком любым пользователем информационной базы. В клиент-серверной информационной базе доступ к базе данных, как правило, имеется только у администраторов СУБД.

      \n

      Таким образом, следует запрашивать логин и пароль у пользователя и передавать их сразу, не сохраняя в информационной базе.

      \n

      3. В ряде случаев такая схема работы доставляет объективные неудобства или принципиально невозможна:

      \n
        \n
      • интерактивный запрос логина и пароля на каждую операцию может создавать значительный дискомфорт от работы, а временного сохранения на стороне клиента недостаточно; \n
      • взаимодействие с различными внешними ресурсами должно выполняться на сервере, не зависимо от интенсивности работы пользователей с программой.
      \n

      В таких случаях допустимо организовать хранение паролей и другой конфиденциальной информации в информационной базе, предупредив пользователей о последствиях. Следует помнить, что подобное хранение паролей не решает всех проблем безопасности, а лишь усложняет задачу для злоумышленника.

      \n

      3.1. При этом не следует хранить пароли и другую конфиденциальную информацию в реквизитах тех же объектов метаданных, с которыми ведется повседневная работа. Для хранения такой информации следует использовать отдельный объект метаданных (например, регистр сведений), организовав к нему безопасный доступ на уровне системы прав доступа 1С:Предприятия.

      \n

      3.2. При использовании Библиотеки стандартных подсистем (БСП) следует использовать безопасное хранилище паролей, которое решает ряд задач:

      \n
        \n
      • Имея доступ к объекту метаданных, пользователь может прочитать содержимое реквизита с паролем, что невозможно при использовании безопасного хранилища. Для исключения случаев несанкционированного доступа к безопасному хранилищу получение и запись данных (паролей) возможна только в привилегированном режиме. \n
      • Данные в безопасном хранилище хранятся в закрытом виде и тем самым исключаются случаи непредумышленной «засветки» паролей. \n
      • Безопасное хранилище исключено из планов обмена, что предотвращает утечку паролей из информационной базы при обмене данными.
      \n

      Для работы с безопасным хранилищем паролей предназначены процедуры и функции общего модуля ОбщегоНазначения: ЗаписатьДанныеВБезопасноеХранилищеПрочитатьДанныеИзБезопасногоХранилища и УдалитьДанныеИзБезопасногоХранилища. Подробнее см. комментарии к этим функциям в БСП и раздел «3.4. Базовая функциональность - Использование при разработке конфигурации - Безопасное хранилище паролей» документации БСП.

      \n

      3.3. Не следует хранить пароли в реквизитах формы, их следует извлекать только на стороне сервера и непосредственно перед их использованием. В противном случае, при открытии формы с маскированным вводом (или просмотром) пароля, пароль передается с  сервера на клиент в открытом виде, что делает возможным его перехват. Установка привилегированного режима производится непосредственно перед вызовом функций, а не внутри них, что бы исключить получение или запись любых паролей в сеансе с любыми правами. Безопасность вызова должен обеспечивать вызывающий код, который обращается к конкретным паролям.

      \n

      Для маскировки пароля на форме в обработчике событии формы ПриСозданииНаСервере необходимо разместить следующий код:

      \n

       УстановитьПривилегированныйРежим(Истина);
       Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Объект.Ссылка, \"Пароль, ПарольSMTP\"); // Пароль, ПарольSMTP – ключи соответствия данных в безопасном хранилище
       УстановитьПривилегированныйРежим(Ложь);

      \n

       Пароль = ?(ЗначениеЗаполнено(Пароли.Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       ПарольSMTP = ?(ЗначениеЗаполнено(Пароли.ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");

      \n

      В обработчике события формы ПриЗаписиНаСервере:

      \n

       Если ПарольИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
        УстановитьПривилегированныйРежим(Ложь);
        Пароль = ?(ЗначениеЗаполнено(Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;
       
       Если ПарольSMTPИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ПарольSMTP, \"ПарольSMTP\");
        УстановитьПривилегированныйРежим(Ложь);
        ПарольSMTP = ?(ЗначениеЗаполнено(ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;

      \n

      где Пароль и ПарольSMTP - реквизиты формы. Если пароль ранее был сохранен в программе, то следует присвоить соответствующему реквизиту уникальный идентификатор формы, эмулирующий наличие пароля. При записи объекта в форме, если был введен новый пароль, то записываем его в объект, а реквизит формы вновь затираем уникальным идентификатором.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "341", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка видимости для элемента формы.", +"Description": "

      Проверка прав доступа

      #std737

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

      \n
        \n
      • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
      • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
      \n

      Эти меры позволяют:

      \n
        \n
      • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
      • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
      • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
      \n

      2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

      \n

      3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
      Например, неправильно:

      \n

      Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
      Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

      \n

      правильно:

      \n

      Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
      Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

      \n

      Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

      \n

      4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
      Например, без использования БСП:

      \n

      Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

      \n

      Либо аналогичная проверка с использованием БСП:

      \n

      Если Пользователи.РолиДоступны(...) Тогда ...

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "345", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Небезопасное хранение паролей в информационной базе.", +"Description": "

      Безопасное хранение паролей

      #std740

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. При разработке подсистем, взаимодействующих с различными внешними ресурсами (электронной почтой, веб-сервисами, FTP-ресурсами и т.п.) возникает необходимость запрашивать и передавать данные аутентификации к этим ресурсам: логин и пароль.

      \n

      2. Для сведения к минимуму возможности перехвата пароля злоумышленниками не следует хранить пароли и другую конфиденциальную информацию в информационной базе. При этом минимальный уровень защищенности – в файловых информационных базах, в которых файл базы может быть скопирован целиком любым пользователем информационной базы. В клиент-серверной информационной базе доступ к базе данных, как правило, имеется только у администраторов СУБД.

      \n

      Таким образом, следует запрашивать логин и пароль у пользователя и передавать их сразу, не сохраняя в информационной базе.

      \n

      3. В ряде случаев такая схема работы доставляет объективные неудобства или принципиально невозможна:

      \n
        \n
      • интерактивный запрос логина и пароля на каждую операцию может создавать значительный дискомфорт от работы, а временного сохранения на стороне клиента недостаточно; \n
      • взаимодействие с различными внешними ресурсами должно выполняться на сервере, не зависимо от интенсивности работы пользователей с программой.
      \n

      В таких случаях допустимо организовать хранение паролей и другой конфиденциальной информации в информационной базе, предупредив пользователей о последствиях. Следует помнить, что подобное хранение паролей не решает всех проблем безопасности, а лишь усложняет задачу для злоумышленника.

      \n

      3.1. При этом не следует хранить пароли и другую конфиденциальную информацию в реквизитах тех же объектов метаданных, с которыми ведется повседневная работа. Для хранения такой информации следует использовать отдельный объект метаданных (например, регистр сведений), организовав к нему безопасный доступ на уровне системы прав доступа 1С:Предприятия.

      \n

      3.2. При использовании Библиотеки стандартных подсистем (БСП) следует использовать безопасное хранилище паролей, которое решает ряд задач:

      \n
        \n
      • Имея доступ к объекту метаданных, пользователь может прочитать содержимое реквизита с паролем, что невозможно при использовании безопасного хранилища. Для исключения случаев несанкционированного доступа к безопасному хранилищу получение и запись данных (паролей) возможна только в привилегированном режиме. \n
      • Данные в безопасном хранилище хранятся в закрытом виде и тем самым исключаются случаи непредумышленной «засветки» паролей. \n
      • Безопасное хранилище исключено из планов обмена, что предотвращает утечку паролей из информационной базы при обмене данными.
      \n

      Для работы с безопасным хранилищем паролей предназначены процедуры и функции общего модуля ОбщегоНазначения: ЗаписатьДанныеВБезопасноеХранилищеПрочитатьДанныеИзБезопасногоХранилища и УдалитьДанныеИзБезопасногоХранилища. Подробнее см. комментарии к этим функциям в БСП и раздел «3.4. Базовая функциональность - Использование при разработке конфигурации - Безопасное хранилище паролей» документации БСП.

      \n

      3.3. Не следует хранить пароли в реквизитах формы, их следует извлекать только на стороне сервера и непосредственно перед их использованием. В противном случае, при открытии формы с маскированным вводом (или просмотром) пароля, пароль передается с  сервера на клиент в открытом виде, что делает возможным его перехват. Установка привилегированного режима производится непосредственно перед вызовом функций, а не внутри них, что бы исключить получение или запись любых паролей в сеансе с любыми правами. Безопасность вызова должен обеспечивать вызывающий код, который обращается к конкретным паролям.

      \n

      Для маскировки пароля на форме в обработчике событии формы ПриСозданииНаСервере необходимо разместить следующий код:

      \n

       УстановитьПривилегированныйРежим(Истина);
       Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Объект.Ссылка, \"Пароль, ПарольSMTP\"); // Пароль, ПарольSMTP – ключи соответствия данных в безопасном хранилище
       УстановитьПривилегированныйРежим(Ложь);

      \n

       Пароль = ?(ЗначениеЗаполнено(Пароли.Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       ПарольSMTP = ?(ЗначениеЗаполнено(Пароли.ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");

      \n

      В обработчике события формы ПриЗаписиНаСервере:

      \n

       Если ПарольИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
        УстановитьПривилегированныйРежим(Ложь);
        Пароль = ?(ЗначениеЗаполнено(Пароль), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;
       
       Если ПарольSMTPИзменен Тогда
        УстановитьПривилегированныйРежим(Истина);
        ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ПарольSMTP, \"ПарольSMTP\");
        УстановитьПривилегированныйРежим(Ложь);
        ПарольSMTP = ?(ЗначениеЗаполнено(ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, \"\");
       КонецЕсли;

      \n

      где Пароль и ПарольSMTP - реквизиты формы. Если пароль ранее был сохранен в программе, то следует присвоить соответствующему реквизиту уникальный идентификатор формы, эмулирующий наличие пароля. При записи объекта в форме, если был введен новый пароль, то записываем его в объект, а реквизит формы вновь затираем уникальным идентификатором.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "346", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обращение к несуществующему параметру формы.", +"Description": "

      Открытие форм

      #std404

      Область применения: управляемое приложение, мобильное приложение.

      \n

      1. Для открытия форм следует применять метод глобального контекста ОткрытьФорму (при использовании версии платформы 1С:Предприятие 8.2 и более ранних версий - также ОткрытьФормуМодально). Применение альтернативного способа, с получением формы и ее последующим открытием с помощью метода ПолучитьФорму, не рекомендуется.

      Рекомендация обусловлена соображениями 

      \n
        \n
      • повышения устойчивости кода, работающего с формой, за счет разделения программного интерфейса для работы с формой и деталей ее внутренней реализации, \n
      • а также сохранения единой стилистики кода прикладных решений.
      \n

      Кроме того, применение глобального метода ОткрытьФорму гарантирует выполнение инициализации формы на сервере в обработчике ПриСозданииНаСервере. Этот подход помогает сосредоточить весь код инициализации формы в одном месте и исключает \"случайное\" обращение к серверу, связанное с инициализацией формы, между строками кода

      \n

      Форма = ПолучитьФорму(...)

      \n

      и

      \n

      Форма.ОткрытьФорму(...)

      \n
      \n

      См. также: раздел «Открытие управляемой формы» статьи «Минимизация количества серверных вызовов»

      \n

      2. В случаях когда форма требует параметризации при открытии, все ее параметры следует указывать в наборе параметров формы. Таким образом, набор параметров формы декларативно описывает возможности формы по ее параметризации.

      \n

      Параметры формы из этого набора могут быть указаны в вызывающем коде при открытии формы (ОткрытьФорму).

      \n

      3. Не следует применять другие способы параметризации формы при открытии. Например, нужно избегать обращения к методам и свойствам формы после ее открытия.
      Например, вместо

      \n

      МояФорма = Форма.ОткрытьФорму(\"ОбщаяФорма.ПутеводительПоСистеме\");
      МояФорма.Элементы.ГруппаШаг.ТекущаяСтраница = МойФорма.Элементы.ГруппаШаг.Страницы.Приветствие;

      \n

      следует по той же причине использовать параметры формы:

      \n

      ОткрытьФорму(\"ОбщаяФорма.ПутеводительПоСистеме\", Новый Структура(\"РежимОткрытия\", \"Приветствие\"));

      \n

      4. Для получения результата работы формы, вместо непосредственного обращения к элементам и реквизитам формы

      \n

      ФормаВопроса = ПолучитьФорму(\"ОбщаяФорма.ФормаВопроса\");
      ФормаВопроса.ОткрытьМодально();
      Если ФормаВопроса.БольшеНеПоказыватьНапоминание Тогда
      // …

      \n

      следует использовать процедуры-обработчики оповещений, которые будут вызваны при завершении работы пользователя с формой:

      \n

      Оповещение = Новый ОписаниеОповещения(\"БольшеНеПоказыватьНапоминаниеЗавершение\", ЭтотОбъект);
      ОткрытьФорму(\"ОбщаяФорма.ФормаВопроса\",,,,, Оповещение, РежимОткрытияОкнаФормы.БлокироватьВеcьИнтерфейс);
      ...

      \n

      &НаКлиенте
      Процедура БольшеНеПоказыватьНапоминаниеЗавершение(БольшеНеПоказыватьНапоминание, Параметры) Экспорт

        Если БольшеНеПоказыватьНапоминание = Неопределено Тогда
          Возврат;
        КонецЕсли;  

      \n

        Если БольшеНеПоказыватьНапоминание Тогда
        // …

      \n

      КонецПроцедуры

      \n

      При этом возвращаемое значение формы формируется в коде модуля формы с помощью метода формы Закрыть.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций

      \n

      5. Другие ограничения:

      \n
        \n
      • Обработчик события формы ПриОткрытии не должен содержать код по открытию какой-либо другой формы, так как это может привести к нарушению порядка отображения окон. В этом случае рекомендуется использовать обработчик ожидания на короткий интервал или открывать другие формы интерактивно, например, по нажатию на кнопку. \n
      • Не рекомендуется выполнять программное открытие и закрытие формы в одном обработчике. Такие действия должны быть разнесены по времени. Например, закрытие формы можно выполнять в обработчике ожидания. \n
      • При использовании в конфигурации Библиотека стандартных подсистем  и разработке форм (рабочих мест), предназначенных только для внешних пользователей, следует явно блокировать открытие таких форм в сеансах \"обычных\" пользователей. Для этого следует устанавливать параметр Отказ при создании формы на сервере с помощью функции ЭтоСеансВнешнегоПользователя общего модуля Пользователи или ПользователиКлиент:
      \n

      &НаСервере
      Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       
        Если Не ПользователиКлиентСервер.ЭтоСеансВнешнегоПользователя() Тогда
          Отказ = Истина;
          Возврат;
        КонецЕсли;
        …
      КонецПроцедуры

      \n

      6. Следующие виды форм должны быть всегда доступны пользователю в режиме 1С:Предприятия из меню \"Все функции\" вне зависимости от того, размещены ли соответствующие объекты в командном интерфейсе приложения или нет:

      \n
        \n
      • \n
        основная форма списка (для всех объектов)
        \n
      • \n
        основная форма обработки
        \n
      • \n
        основная форма отчета
      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "347", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не задан синоним стандартного реквизита \"Родитель\".", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "349", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Синоним стандартного реквизита \"Владелец\" совпадает с наименованием.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "350", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Синоним стандартного реквизита \"Родитель\" совпадает с наименованием.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "351", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Бессмысленное (автосгенерированное) имя элемента формы.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "352", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Бессмысленное (автосгенерированное) имя реквизита формы.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "353", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Бессмысленное (автосгенерированное) имя команды формы.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "354", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Бессмысленное (автосгенерированное) имя параметра формы.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "355", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в имени команды формы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "359", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Ограничения на уровне записей в разных ролях не совпадает для той же таблицы и права.", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "360", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Ограничения для права \"Добавление\" не совпадает с ограничением права \"Изменение\".", +"Description": "

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "361", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Серверный код не заключен в инструкцию препроцессора: \"#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда...\".", +"Description": "

      Поддержка толстого клиента, управляемое приложение, клиент-сервер

      #std680

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В управляемом режиме из-за ряда ограничений тонкого клиента может возникнуть необходимость поддержки запуска толстого клиента (в режиме управляемого приложения). Подробнее см. Функциональность обычного приложения, отсутствующая в управляемом приложении.

      \n

      2. При этом разработка конфигураций, рассчитанных на режим управляемого приложения, как правило, ведется исходя из того, что в клиент-серверной архитектуре код следующих модулей компилируется и выполняется только на сервере

      \n
        \n
      • модуль менеджера; \n
      • модуль объекта; \n
      • модуль сеанса.
      \n

      В частности, в указанных модулях может встречаться обращение к общим модулям, доступным только на сервере.

      \n

      Однако в толстом клиенте, в режиме управляемого приложения, клиент-сервер, возможны ситуации, когда указанные модули могут начать компилироваться и выполняться на стороне клиента, в частности:

      \n
        \n
      • если объект (справочник, документ и т.п.) явно создается и вызывается в клиентском коде; \n
      • когда платформа 1С:Предприятие неявно обращается к модулям менеджеров и модулю сеанса для вызова их обработчиков событий на клиенте.
      \n

      Компиляция и выполнение таких модулей на клиенте могут приводить к ошибкам. По этой причине режим проверки конфигурации для режима толстый клиент, управляемое приложение, может находить ошибки в указанных модулях.

      \n

      Для того чтобы избежать незапланированной компиляции и исполнения указанных модулей на клиенте, а также чтобы избежать лишних сообщений режима проверки конфигурации, следует:

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей объектов (наборов записей и т.п.), заключив его в инструкцию препроцессора и дополнив вызовом исключения, которое предотвращает несанкционированную попытку использования объекта на клиенте:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #Иначе
        ВызватьИсключение НСтр(\"ru = 'Недопустимый вызов объекта на клиенте.'\");
      #КонецЕсли

      \n
        \n
      • полностью исключить из клиентского контекста код модуля сеанса, заключив его в инструкцию препроцессора (так как параметры сеанса требуются для работы серверного, а не клиентского кода конфигурации):
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #КонецЕсли

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей менеджеров всех видов объектов метаданных, заключив его в инструкцию препроцессора:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

      #КонецЕсли

      \n

      В последнем случае также будет действовать следующее ограничение: если представление объектов формируется обработчиками событий модуля менеджера ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления, то в толстом клиенте, в режиме управляемого приложения, клиент-сервер, представление будет формироваться по умолчанию, без вызова этих обработчиков, и тем самым будет отличаться от остальных режимов работы. (При этом оставшиеся два обработчика модуля менеджера ОбработкаПолученияДанныхВыбора и ОбработкаПолученияФормы вызываются всегда только на сервере, поэтому указанное ограничение на них не распространяется.)

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      3. В тех случаях, когда требуется снять указанное выше ограничение, необходимо дополнительно обеспечить работу на клиенте следующих фрагментов серверного кода:

      \n
        \n
      • обработчиков событий модулей менеджеров ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления \n
      • а также код подписок на эти события модулей менеджеров.
      \n

      Для этого код перечисленных обработчиков событий следует вынести за инструкции препроцессора, указанные в п.2, а обработчики подписок разместить в клиент-серверных модулях.

      \n

      При необходимости вызова серверных процедур (и функций) из клиентского кода следует размещать вызываемые процедуры в серверных общих модулях с признаком Вызов сервера. При этом нужно убедиться, что в параметры процедур (и в возвращаемые значения функций) не передаются значения мутабельных типов (СправочникОбъект, ДокументОбъект и пр.)

      \n

      Важно: не следует для этих целей всем общим модулям с признаком Сервер принудительно устанавливать флажок Вызов сервера. Подробнее см. Ограничение на установку признака «Вызов сервера» у общих модулей.

      \n

      Например, обработчик события ОбработкаПолученияПредставления вызывает общий модуль, который не доступен на клиенте:

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
       
        Взаимодействия.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;
       
      КонецПроцедуры

      \n

      правильно выполнить переход на сервер (и при этом не передавать на клиент значения мутабельных типов):

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)

        ВзаимодействияВызовСервера.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;

      \n

      КонецПроцедуры

      \n

      4. Для расстановки фрагментов кода с инструкциями препроцессора можно воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "362", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обработчик события заключен в инструкцию препроцессора: \"#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда...\".", +"Description": "

      Поддержка толстого клиента, управляемое приложение, клиент-сервер

      #std680

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В управляемом режиме из-за ряда ограничений тонкого клиента может возникнуть необходимость поддержки запуска толстого клиента (в режиме управляемого приложения). Подробнее см. Функциональность обычного приложения, отсутствующая в управляемом приложении.

      \n

      2. При этом разработка конфигураций, рассчитанных на режим управляемого приложения, как правило, ведется исходя из того, что в клиент-серверной архитектуре код следующих модулей компилируется и выполняется только на сервере

      \n
        \n
      • модуль менеджера; \n
      • модуль объекта; \n
      • модуль сеанса.
      \n

      В частности, в указанных модулях может встречаться обращение к общим модулям, доступным только на сервере.

      \n

      Однако в толстом клиенте, в режиме управляемого приложения, клиент-сервер, возможны ситуации, когда указанные модули могут начать компилироваться и выполняться на стороне клиента, в частности:

      \n
        \n
      • если объект (справочник, документ и т.п.) явно создается и вызывается в клиентском коде; \n
      • когда платформа 1С:Предприятие неявно обращается к модулям менеджеров и модулю сеанса для вызова их обработчиков событий на клиенте.
      \n

      Компиляция и выполнение таких модулей на клиенте могут приводить к ошибкам. По этой причине режим проверки конфигурации для режима толстый клиент, управляемое приложение, может находить ошибки в указанных модулях.

      \n

      Для того чтобы избежать незапланированной компиляции и исполнения указанных модулей на клиенте, а также чтобы избежать лишних сообщений режима проверки конфигурации, следует:

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей объектов (наборов записей и т.п.), заключив его в инструкцию препроцессора и дополнив вызовом исключения, которое предотвращает несанкционированную попытку использования объекта на клиенте:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #Иначе
        ВызватьИсключение НСтр(\"ru = 'Недопустимый вызов объекта на клиенте.'\");
      #КонецЕсли

      \n
        \n
      • полностью исключить из клиентского контекста код модуля сеанса, заключив его в инструкцию препроцессора (так как параметры сеанса требуются для работы серверного, а не клиентского кода конфигурации):
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
        …
      #КонецЕсли

      \n
        \n
      • \n
        полностью исключить из клиентского контекста код модулей менеджеров всех видов объектов метаданных, заключив его в инструкцию препроцессора:
      \n
      \n

      #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

      #КонецЕсли

      \n

      В последнем случае также будет действовать следующее ограничение: если представление объектов формируется обработчиками событий модуля менеджера ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления, то в толстом клиенте, в режиме управляемого приложения, клиент-сервер, представление будет формироваться по умолчанию, без вызова этих обработчиков, и тем самым будет отличаться от остальных режимов работы. (При этом оставшиеся два обработчика модуля менеджера ОбработкаПолученияДанныхВыбора и ОбработкаПолученияФормы вызываются всегда только на сервере, поэтому указанное ограничение на них не распространяется.)

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      3. В тех случаях, когда требуется снять указанное выше ограничение, необходимо дополнительно обеспечить работу на клиенте следующих фрагментов серверного кода:

      \n
        \n
      • обработчиков событий модулей менеджеров ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления \n
      • а также код подписок на эти события модулей менеджеров.
      \n

      Для этого код перечисленных обработчиков событий следует вынести за инструкции препроцессора, указанные в п.2, а обработчики подписок разместить в клиент-серверных модулях.

      \n

      При необходимости вызова серверных процедур (и функций) из клиентского кода следует размещать вызываемые процедуры в серверных общих модулях с признаком Вызов сервера. При этом нужно убедиться, что в параметры процедур (и в возвращаемые значения функций) не передаются значения мутабельных типов (СправочникОбъект, ДокументОбъект и пр.)

      \n

      Важно: не следует для этих целей всем общим модулям с признаком Сервер принудительно устанавливать флажок Вызов сервера. Подробнее см. Ограничение на установку признака «Вызов сервера» у общих модулей.

      \n

      Например, обработчик события ОбработкаПолученияПредставления вызывает общий модуль, который не доступен на клиенте:

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
       
        Взаимодействия.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;
       
      КонецПроцедуры

      \n

      правильно выполнить переход на сервер (и при этом не передавать на клиент значения мутабельных типов):

      \n

      Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)

        ВзаимодействияВызовСервера.ОбработкаПолученияПредставления(Данные, Представление);
        СтандартнаяОбработка = Ложь;

      \n

      КонецПроцедуры

      \n

      4. Для расстановки фрагментов кода с инструкциями препроцессора можно воспользоваться приложенной обработкой.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "363", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не следует добавлять постфикс \"Клиент\" в наименование глобального общего модуля с постфиксом \"Глобальный\".", +"Description": "

      Правила создания общих модулей

      #std469

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

      \n

      1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
      (обычное приложение)
      Клиент
      (управляемое приложение)
      1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

       

      2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

      +

      \n

      +

      \n

       

      \n

       

      3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

       

      \n

       

      \n

       

      \n

      +

      \n

      +

      4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

       

      \n

      +

      \n

      +

      \n

      +

      \n

      +

      \n

      \n

      2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
      Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

      \n
        \n
      • Сервер (флажок Вызов сервера сброшен), \n
      • Клиент (обычное приложение), \n
      • Внешнее соединение
      \n

      В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

      \n
        \n
      • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
      • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
      \n

      Серверные общие модули называются по общим правилам именования объектов метаданных.
      Например: РаботаСФайлами, ОбщегоНазначения

      \n

      В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
      Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

      \n

      2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
      Такие процедуры и функции размещаются в общих модулях с признаком:

      \n
        \n
      • Сервер (флажок Вызов сервера установлен)
      \n

      Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
      Например: РаботаСФайламиВызовСервера, CommonServerCall

      \n

      Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

      \n
      \n

      См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

      \n

      2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Клиент (обычное приложение)
      \n

      Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

      \n

      Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
      Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

      \n
      \n

      См. также: минимизация кода, выполняемого на клиенте

      \n

      2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

      \n
        \n
      • Клиент (управляемое приложение) \n
      • Сервер (флажок Вызов сервера сброшен) \n
      • Клиент (обычное приложение) \n
      • Внешнее соединение
      \n

      Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
      Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

      \n

      В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

      \n
      \n

      Подробнее см.: Использование директив компиляции и инструкций препроцессора

      \n

      Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

      \n

      3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

      \n

      Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

      \n

      3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

      \n

      3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
      Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

      \n

      3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
      Например: РаботаСФайламиПолныеПрава

      \n

      3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
      Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

      \n

      3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
      Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

      \n
      \n

      См. также: Переопределяемые и поставляемые объекты библиотеки

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "370", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Параметр \"ИмяСобытия\" метода \"ЗаписьЖурналаРегистрации()\" инициализируется переменной, содержащей нелокализованную строку.", +"Description": "

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n\n\n\n

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "371", +"Type": "BUG", +"Severity": "MINOR", +"Name": "При локализации параметра \"ИмяСобытия\" для получения кода языка следует использовать функцию ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка().", +"Description": "

      Автогенерированные данные в информационной базе: требования по локализации

      #std784

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Автогенерируемые строки, которые программно записываются в информационную базу и выводятся пользователям, необходимо формировать не на языке текущего пользователя, а на языке информационной базы.

      \n

      Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.

      \n

      В противном случае, если документ провел пользователь с русскоязычным интерфейсом, а затем тот же документ перепровел пользователь с англоязычным интерфейсом, то содержание записей регистра бухгалтерии станет другим (что ошибочно).

      \n

      Такие места в коде рекомендуется сопровождать комментарием, поясняющим, что строка является данными, а не интерфейсным текстом:

      \n

      Неправильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\");
      \n

      Правильно:

          Комментарий = НСтр(\"ru = 'Комментарий к проводке'\", КодОсновногоЯзыка); // строка записывается в ИБ\n
      \n

      Где КодОсновногоЯзыка – код языка хранения данных в информационной базе, выбранный в момент первого запуска программы из языков интерфейса конфигурации и сохраненный в константе ОсновнойЯзык. \n

      При использовании в конфигурации Библиотеки стандартных подсистем для получения кода языка для хранения данных следует использовать функцию КодОсновногоЯзыка общего модуля ОбщегоНазначения.

        \nКомментарий = НСтр(\"ru = 'Комментарий к проводке'\", ОбщегоНазначения.КодОсновногоЯзыка()); // строка записывается в ИБ 
      \n

      2. Аналогичные требования распространяются и на обработчики начального заполнения заполняющих строковые реквизиты предопределенных элементов справочников, ПВХ и т.п. \n

      Правильно:

      Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт\n\u0009Обработчик = Обработчики.Добавить();\n\u0009Обработчик.НачальноеЗаполнение = Истина;\n\u0009Обработчик.Процедура = \"ПользователиСлужебный.ЗаполнитьНаименованиеПредопределенныхГруппПользователей\";\nКонецПроцедуры\n\nПроцедура ЗаполнитьНаименованиеПредопределенныхГруппПользователей() Экспорт\n\u0009ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи.ПолучитьОбъект();\n\u0009ГруппаПользователей.Наименование = НСтр(\"ru='Все пользователи'\", КодОсновногоЯзыка);\n\u0009ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаПользователей); \nКонецПроцедуры\n
      \n

      При добавлении новых предопределенных элементов, необходимо создать новый обработчик начального заполнения с указанием версии или дополнить существующий. См. также стандарт Обработчики обновления информационной базы. \n

      При использовании в конфигурации Библиотеки стандартных подсистем не следует создавать собственные обработчики начального заполнения. Первоначальные данные заполнения нужно размещать в модуле менеджера объекта в процедуре ПриНачальномЗаполненииЭлементов. Тогда для объектов, зарегистрированных в процедуре ПриОпределенииНастроек общего модуля ОбновлениеИнформационнойБазыПереопределяемый, эти процедуры будут вызваны автоматически. \n

      При добавлении нового или изменении существующего элемента следует создать собственный обработчик обновления перехода на версию и продублировать изменения в процедуре ПриНачальномЗаполненииЭлементов модуля менеджера объекта. Подробнее см. документацию к БСП.

      \n\n\n

      Использование Журнала регистрации

      #std498

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. Журнал регистрации предназначен для хранения событий, возникающих в процессе работы пользователей с информационной базой. При администрировании эту информацию часто необходимо анализировать в различных разрезах для того, чтобы например, узнать какие события происходили в определенный момент времени, какие действия выполнял тот или иной пользователь.

      \n

      2. Рекомендуется производить запись в Журнал регистрации из встроенного языка в тех случаях, когда администратору необходимо сообщить дополнительную диагностическую информацию о событиях, которые не записываются платформой 1С:Предприятие. Такая необходимость может возникнуть как при выполнении бизнес-логики, вызываемой при интерактивной работе, так и в фоновых (регламентных) заданиях. Для удобства анализа Журнала регистрации одна его запись должна соответствовать одному событию, а сами записи должны содержать ряд обязательных атрибутов, в разрезе которых проводится анализ.

      \n

      2.1. Строковый идентификатор типа события. Как правило, список типов событий в конфигурации может быть сколь угодно большим, поэтому типы событий рекомендуется группировать по функциональному признаку: «Название группы событий.Название события». Например, правильно записывать события с типами «Поручения.Уведомление о новых задачах» и «Поручения.Уведомление о зависших задачах» вместо двух «плоских» типов событий «Уведомление о новых задачах» и «Уведомление о зависших задачах». Текст типа события – локализуем, при этом всегда задается основной язык конфигурации.

      \n

      2.2. Уровень важности события. Критичные события, требующие повышенного внимания администратора (ошибки бизнес-логики, сбои в программе, и т.п.), записываются в Журнал регистрации с уровнем важности «Ошибка». Потенциальные проблемы и не фатальные ошибки регистрируются как «Предупреждения». Для вывода информационных сообщений об успешном завершении той или иной операции используется уровень важности «Информация». Также возможно применять и более низкий уровень важности – «Примечание».

      \n

      2.3. Комментарий. Содержит текстовую неструктурированную информацию о событии. В случае ошибок в этом поле содержится информация, необходимая для расследования причины проблемы. Не следует помещать в комментарий информацию сразу о нескольких событиях. Например, неправильно записывать одно событие с комментарием вида:

      \n

      [01.01.2010 00:00:01] Начало инициализации обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:02] Окончание инициализации обмена данными (успешно)
      [01.01.2010 00:00:03] Начало процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:04] Начало записи изменений в файл обмена
      [01.01.2010 00:00:05] Окончание записи изменений в файл обмена (успешно)
      [01.01.2010 00:00:06] Окончание процесса обмена данными по настройке \"Обмен данными выгрузка\", номер строки настройки: 1
      [01.01.2010 00:00:07] Выполнено, Выгрузка данных, Обработано 1 объектов

      \n

      правильно записать столько событий, сколько их реально произошло.

      \n

      Текст комментария – локализуем. Для записи в Журнал регистрации информации о возникшем исключении следует использовать конструкцию:

      \n

      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())

      \n

      Пример регистрации дополнительных событий в функциональной подсистеме «Мой механизм»:

      \n

      Попытка 
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Начато действие'\"));
       ДействиеСВозможнойОшибкой(ОбъектДействия);
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Информация, , ,
        НСтр(\"ru = 'Завершено действие'\");
      Исключение
       ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие с возможной ошибкой'\", КодОсновногоЯзыка),
        УровеньЖурналаРегистрации.Ошибка, , ,
        НСтр(\"ru = '\"Во время выполнения действия произошла неизвестная ошибка.'\") + Символы.ПС +
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
       КонецПопытки;  
      КонецПроцедуры

      \n

      где переменная КодОсновногоЯзыка содержит код языка для хранения данных в информационной базе. Подробнее см. Автогенерированные данные в информационной базе: требования по локализации, п. 1.

      \n

      3. Не следует использовать выборку из журнала регистрации в тех задачах, где критична высокая скорость выполнения выборки. Поскольку при больших объемах журнала регистрации скорость выборки падает пропорционально увеличению его объема.

      \n

      Рекомендуется заводить отдельный регистр для протоколирования интересующих событий или обращаться к специализированным объектам платформы (например, МенеджерФоновыхЗаданий для выборки истории выполнения фоновых заданий).

      \n

      Эту особенность нужно также учитывать при разработке отчетов по журналу регистрации.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "374", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Сообщение содержит восклицательный знак.", +"Description": "

      Сообщения пользователю

      #std585

      Область применения: управляемое приложение.

      \n

       

      \n

      1. Общие рекомендации

      \n

       

      \n

      1.1. Сообщения должны быть достаточно информативными и содержательными. Сообщения составляются в форме безличного предложения: не употребляются местоимения \"Вы\", \"Вас\" и пр.  

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Недостаточно прав для выполнения обработки\"

      \n

      \"У Вас недостаточно прав для выполнения обработки\"

      \n

       

      \n

      1.2. Сообщения не должны содержать восклицательных знаков и повелительных тонов, за исключением сообщений, предупреждающих об опасных или критических действиях. 

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Внимание. Загрузка базы может привести к потере всех данных\"

      \n

       

      \n

       

      \n

       

      \n

       

      \n

      \"Выберите элемент, а не группу\"

      \n

       

      \n

      \"Внимание! Загрузка базы может привести к потере всех данных\"

      \n

      Это сообщение не акцентирует внимание пользователя на том, что последствия могут критичны

      \n


      \"Выберите элемент, а не группу!\"

      \n

      Это сообщение несет негативный настрой, а также заставляет пользователя чувствовать себя глупо

      \n

       

      \n

      1.3. Сообщение должно быть написано текстом, понятным пользователю. В частности, оно не должно содержать технической терминологии (терминологии разработчика). Подобную терминологию допускается использовать только в сообщениях, предназначенных для администратора.

      \n

      Например, если пользователь указал в качестве кассы отправителя и кассы получателя одно и то же значение, то выводится  сообщение: \"Касса отправителя равна кассе получателя\".

      \n

      В реальности касса не может быть равна другой – она может быть одной и той же.

      \n


       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Касса отправителя и касса получателя должны различаться\"

      \n

      \"Касса отправителя равна кассе получателя\"

      \n

       

      \n

      1.4. Сообщения, указывающие на ошибку, должны выводиться в момент возникновения ошибки.

      \n

      Например, в отчете, сдаваемом в Пенсионный фонд, указываются  регистрационные номера сотрудников. Эти номера заполняются в карточке сотрудника.
      Проверку  правильности заполнения этого номера нужно делать в момент его  ввода в карточке, а не в момент формирования отчета.

      \n

       

      \n

      1.5. В тексте сообщений необходимо избегать двусмысленности. Категорически запрещается постановка вопроса с содержанием частиц \"не\" и \"бы\". Подобные вопросы не способны дать однозначного ответа.

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Удалить файл?\"

      \n

      \"Не хотели бы вы удалить этот файл?\" (Да / Нет)
      \"Переместить или удалить этот файл?\" (Да / Нет)

      \n

       

      \n

      1.6. В текстах сообщений не следует использовать сокращения и аббревиатуры. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения и аббревиатуры.
      Например, сокращения \"НДС\", \"МСФО\" понятны пользователям, а \"К.\" (коэффициент) – нет.

      \n

       

      \n

      1.7. Если текст сообщения занимает несколько строк, рекомендуется составлять его таким образом, чтобы строки оканчивались на логическую паузу или завершались знаком препинания.

      \n

       

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      Не рекомендуется изменять значение ставки налога,
      если она уже используется в справочниках или документах.

      \n

      Не рекомендуется изменять значение ставки налога, если
      она уже используется в справочниках или документах.

      \n

       

      \n

      1.8. Следует руководствоваться принципом, что в процедурах и функциях, выполняемых в транзакции, нельзя выполнять каких-либо взаимодействий с пользователем – выводить предупреждения и вопросы.

      \n

       

      \n

      1.9. Сообщения, оповещения, предупреждения или состояние не следует использовать в случае, если нужно вывести протокол, отчет или подробности о результатах выполненной операции. Для этого следует предусмотреть специальную форму.

      \n

      2. Сообщение об ошибках в форме

      \n

      \n

      Сообщения об ошибках в форме выводятся в панели сообщений об ошибках справа:

      \n

      \n

       

      \n

      2.1. В панели сообщений следует выводить только сообщения об ошибках. Сообщения об успешном завершении операции в панели выводить запрещается.

      \n


       

      \n

      2.2. Сообщение об ошибке по возможности должно быть привязано к полю, которое породило ошибку или позволяет исправить ее. Если сообщение нельзя привязать к тому или иному полю, то в тексте сообщения следует явно указать, что пользователю нужно сделать для того, чтобы устранить проблему.

      \n

       

      \n

      2.3. Сообщения об ошибках должны отвечать на 3 вопроса:

      \n
        \n
      • Что произошло? \n
      • Почему это произошло? \n
      • Что делать дальше?
      \n

      Ответов на эти вопросы должно хватить пользователю, чтобы принять решение о дальнейших действиях, а также не повторить данной ошибки в будущем.

      \n

      Например, пользователь пытается изменить статус документа, помеченного на удаление.
      Система выдает сообщение: \"Документ \"Коммерческое предложение <номер> не проведен. Статус не изменен\"

      \n

      Сообщение создает новый вопрос для пользователя: почему не изменен статус? В тексте сообщения отсутствует информация о том, что документ помечен на удаление, и что именно это является причиной возникновения ошибки.

      \n

       

      \n

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Невозможно изменить статус: документ \"Коммерческое предложение <номер> помечен на удаление\"

      \n

      \"Документ \"Коммерческое предложение <номер> не проведен. Статус не изменен\"

      \n

      2.4. Следует учитывать, что в панели сообщений текст сообщения автоматически форматируется, а строки переносятся, сохраняя при этом свои пропорции. Поэтому текст таких сообщений не нужно разбивать на строки.

      \n

      См. также: Перенос выражений

      \n

      2.5. Сообщение должно быть как можно более кратким и понятным.
      Если же поле заполнено, но неправильно, то сообщение должно быть более подробным.
      Например, \"Указанного количества товара <название товара> нет на складе. Доступно: <количество доступно> <единица измерения>\".

      \n

      2.6. Текст сообщения об ошибке должен содержать побудительную часть, призывающую пользователя совершить действия по исправлению ошибки.

      \n

      \n\n\n\n\n\n\n\n
      \n

      Правильно

      \n

      Неправильно

      \n

      \"Укажите хотя бы одну систему налогообложения\"

      \n

       

      \n

      \"Необходимо указать хотя бы одну систему налогообложения\"

      \n

       

      \n

      3. Оповещение

      \n

       

      \n

      \n

      \n

      \n

      3.1. Рекомендуется использовать оповещение для информирования пользователя о произошедших событиях без прерывания основной работы. Пользователю не обязательно реагировать на оповещение, оно выдается для информации.
      Оповещение сообщает о том, что запрошенная операция (запись элемента справочника или проведение документа) выполнена.

      \n

       

      \n

      3.2. Оповещения рекомендуется делать с гиперссылками на соответствующие объекты.

      \n

       

      \n

      3.3. Текст и пояснение оповещения рекомендуется составлять так, чтобы они целиком помещались в окне оповещения с размерами \"по умолчанию\":

      \n
        \n
      • Текст – 36 знаков; \n
      • Пояснение  – около 100 знаков (с учетом переноса на три строки).
      \n

       

      \n

      4. Состояние

      \n

       

      \n

      4.1. Рекомендуется использовать состояние для информирования о выполнении длительных процессов (занимающих более 10 секунд), чтобы у пользователей не сложилось впечатление о том, что программа \"зависла\". Выводите состояние:

      \n

      ·        перед началом выполнения (\"Выполняется расчет. Пожалуйста, подождите…\")

      \n

      ·        в процессе выполнения (если есть возможность)

      \n

      ·        при завершении (\"Расчет выполнен\")

      \n

       

      \n

      4.2. Состояние используется для длительных операций, состоящих из некоторого числа более мелких операций.
      Например, при переносе файлов с жесткого диска в информационную базу можно выводить состояние для каждого переносимого файла:

      \n

       

      \n

      \n

       

      \n

      См. также: Длительные операции, Запись событий в историю работы пользователя

      \n

       

      \n

       

      \n

       

      \n

      5. Предупреждение

      \n

       

      \n

      5.1. Предупреждение рекомендуется использовать только в тех случаях, когда необходимо прервать работу пользователя, чтобы он ознакомился с некоторой информацией. При этом для возобновления работы пользователю не нужно принимать решений.

      \n

       

      \n

      5.2. Не следует использовать предупреждение для информирования о начале выполнения длительных обработок. Такое сообщения следует выдавать непосредственно в форме обработки.

      5.3. В тексте предупреждения следует привести законченные пояснения о последующих действиях и их последствиях.

      \n

      Например, пользователь пытается заполнить цены товаров в табличной части \"Товары\" документа «Заказ клиента». Программа выдает предупреждение о невозможности выполнения этого действия:

      \n

       

      \n

      \n

       

      \n

       

      \n

      6. Вопросы в сообщениях

      \n

       

      \n

      6.1. Рекомендуется использовать в тех случаях, когда необходимо, чтобы пользователь принял решение, например, о продолжении начатой операции.

      \n

       

      \n

      6.2. Вопросы рекомендуется выдавать перед выполнением:

      \n

      ·         действий, результаты которых отменить потом невозможно

      \n

      ·         потенциально опасных для данных пользователя действий

      \n

      ·         массовой обработки информационной базы

      \n

      ·         длительных процедур

      \n

       

      \n

      6.3. Ответами на вопрос должны выступать глаголы, обозначающие последующие действия.

      \n

      Например:

      \n

       

      \n

      \n

       

      \n

      6.4.  В сообщениях-вопросах кнопкой по умолчанию должна являться та кнопка, выбор которой наиболее безопасен для данных пользователя.
      Например, при сохранении файла кнопкой по умолчанию является \"Сохранить\":

      \n

       

      \n

      \n

       

      \n

      ВАЖНО: Чаще всего в ОС Windows кнопкой по умолчанию является первая (самая левая) кнопка. Прибегать к изменению кнопки по умолчанию рекомендуется только в исключительных ситуациях.

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "375", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Избыточно установлены права на устаревший объект метаданных (с префиксом \"Удалить\").", +"Description": "

      Удаление устаревших объектов метаданных из конфигурации

      #std534

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Если при изменении структуры метаданных конфигурации планируется удалить объект метаданных (реквизит, измерение, ресурс и пр.), связанный с записями информационной базы, то необходимо принять решение об удалении или переносе данных этого объекта в новые структуры. При переносе данных в другие объекты рекомендуется придерживаться следующих правил. \n

      1.1. Не удалять из конфигурации устаревшие объекты метаданных и реквизиты безвозвратно, а пометить их как устаревшие, добавив к их именам префикс \"Удалить\" (англ. \"Obsolete\"). Например: реквизит \"ОсновнойДоговор\" (англ. \"MainContract\")  должен быть переименован в \"УдалитьОсновнойДоговор\" (англ. \"ObsoleteMainContract\").

      \n

      В синоним устаревшего объекта (реквизита) рекомендуется добавлять префикс \"(не используется)\" (англ. \"(not used)\"), например: \"(не используется) Основной договор\" (англ. \"(not used) Main contract\"). Если же устарел стандартный реквизит, то префикс \"(не используется)\" также добавляется в его синоним.

      \n

      1.2. После изменения структуры метаданных следует обеспечить перенос данных из устаревших реквизитов в новую структуру метаданных конфигурации.

      \n

      1.3. Если удаляемый объект метаданных является документом – регистратором движений, а соответствующие регистры с движениями остаются в составе конфигурации, то необходимо обратить внимание на необходимость сохранения движений. Для сохранения движений документов – устаревших объектов метаданных, рекомендуется:

      \n
        \n
      • Запретить генерацию движений при проведении документов этого вида. \n
      • Запретить снятие пометки удаления для документов этого вида. \n
      • Во всех существующих движениях документов этого вида изменить регистратор на один или несколько замещающих документов-регистраторов: существующих универсальных или специально разработанных. Например \"Перенос данных\", \"Операция\". \n
      • Пометить все документы этого вида на удаление.
      \n

      1.4. Произвести замену во всей конфигурации обращений к устаревшим реквизитам на обращение к новым данным, поскольку использование устаревших объектов и их реквизитов после изменения структуры метаданных методически неверно. В частности, исключить устаревшие объекты метаданных из всех ролей (кроме ролей ПолныеПрава и АдминистраторСистемы), подписок на события и т.п., а также удалить у них код, формы, макеты, команды и другие элементы, ставшие избыточными.

      \n

      1.5. При сортировке устаревших объектов метаданных и реквизитов в дереве метаданных следует придерживаться общих требований к конфигурации.

      \n

      1.6. Также рекомендуется выполнить очистку устаревших данных с тем, чтобы они не влияли на размер базы и не потребляли ресурсы (при резервном копировании, реструктуризации и других операциях).

      \n

      В случае сложных (ошибкоемких) алгоритмов переноса данных, такую очистку целесообразно проводить не сразу, а через один или несколько релизов. Тем самым, остается возможность выпуска внепланового релиза для устранения последствий некорректной работы алгоритмов переноса.

      \n

      2. Необходимость в переносе данных также может возникнуть при пересмотре структуры измерений регистров. Следует создать новый регистр с правильной структурой, а старый отметить как устаревший и перенести записи из старого регистра в новый в тех случаях, когда измерение регистра сведений становится не актуальным: удаляется, либо изменяется его тип, либо у измерения составного типа уменьшается состав типов.
      При этом создать новый регистр не требуется, если в регистр добавляется новое измерение или у измерения составного типа расширяется состав типов.

      \n

      3. Безвозвратно удалять устаревшие объекты метаданных и реквизиты, помеченные префиксом \"Удалить\" (англ. \"Obsolete\"), следует при выпуске очередных версий конфигурации в том случае, если соблюдается одно из условий:

      \n
        \n
      1. Переход со \"старой\" версии конфигурации на новые версии всегда выполняется пользователями последовательно, \"через\" версию с реализованным переносом данных из \"устаревших\" объектов метаданных и реквизитов. Например: если в конфигурации версии 1.1 реквизит \"ОсновнойДоговор\" был помечен как устаревший, то переход с версии 1.0 на версию 2.0 всегда выполняется только последовательно: сначала на версию 1.1 (в которой происходит обработка устаревших данных), а затем на 2.0 (в которой устаревшие данные могут быть удалены безвозвратно). Непосредственный переход с версии 1.0 на 2.0 технически невозможен (запрещен). \n
      2. Вероятность того, что \"старой\" версией конфигурации еще пользуются, стала нулевой или пренебрежимо малой.
      \n

      При этом может потребоваться выпустить промежуточный релиз, в котором обеспечить очистку устаревших данных - см. п.1.6. В противном случае, может завершиться ошибкой реструктуризация регистров, в измерениях которых остаются ссылки на устаревшие данные.

      \n\n\n

      Настройка ролей и прав доступа

      #std689

      Область применения: управляемое приложение, обычное приложение.

      \n
      \n

      Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
      Для других конфигураций рекомендуется к использованию.
      Содержит уточнения к требованиям других стандартов.

      \n

      1. Общие положения

      \n
      \n

      1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

      \n

      Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

      \n

      Например, в УП(ERP) это роль ПартнерСамообслуживание.

      \n

      1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

      \n

      1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

      \n
        \n
      • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
      \n

      1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

      \n

      1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

      \n

      1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

      \n

      1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

      \n

      Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

      \n

      1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

      \n

      Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
      Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

      \n

      1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

      \n
        \n
      • при создании новой роли нужно следить, чтобы эти права были выключены.
      \n

      1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

      \n

      1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
      Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

      \n

      2. Правила создания ролей к элементарным функциям

      \n

      2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

      \n

      Пример:
      Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

      \n

      Противоположный пример:
      Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

      \n

      2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

      \n

      2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

      \n

      2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

      \n

      3. Ссылочные объекты и регистры

      \n

      3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

      \n
        \n
      • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
      • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
      \n

      Роли должны содержать следующие права (когда они имеются у объекта метаданных):

      \n
        \n
      • \n
        Чтение<ИмяФункции> содержит права:
        \n
          \n
        • \n
          Чтение, Просмотр, Ввод по строке.
        \n
      • \n
        Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Изменение, Редактирование;
          \n
        • \n
          Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
          \n
        • \n
          Управление итогами (для регистров).
        \n
      • \n
        ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
        \n
          \n
        • \n
          Добавление, Интерактивное добавление;
          \n
        • \n
          Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
      \n

      3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

      \n

      4. Журналы документов

      \n

      4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

      4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

      \n

      5. Константы

      \n

      5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

      \n

      5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

      \n

      5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

      \n

      5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

      \n

      Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

      \n

      6. Подсистемы, отображаемые в главном командном интерфейсе

      \n

      6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

      \n

      6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

      \n

      7. Отчеты

      \n

      7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

      \n

      Пример:
      Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

      \n

      7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

      \n

      Пример:
      Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

      \n

      7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

      \n

      Пример:
      Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

      \n

      7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

      \n
        \n
      • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
      • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
      \n

      8. Обработки и общие формы

      \n

      8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

      \n

      При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

      \n

      8.2.  Права ко всем другим типам обработок, например

      \n
        \n
      • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
      • обработки, в которых расположен общий код, например, код формирования печатных форм;
      \n

      должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

      \n

      8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

      8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

      8.5 Исключения из этих правил описаны в п. 6.2

      Пример:
      В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

      \n

      9. Команды

      \n

      9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

      \n
        \n
      • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
      • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
      \n

      9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

      \n

      10. Права, не связанные с доступом к объектам

      \n

      10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

      \n

      Пример:
      Правильно ОтклонениеОтУсловийЗакупок
      Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

      \n

      10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

      \n

      10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

      \n

      11. Права для внешних пользователей

      \n

      Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
      Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

      \n
        \n
      • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
      • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
      • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
      \n

      12. Права к устаревшим объектам

      \n

      Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "376", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Превышена максимальная длина числовых данных (31 знак).", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "377", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Превышена максимальная длина ресурса регистра накопления или бухгалтерии (25 знаков).", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "379", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В качестве правого операнда операции сравнения \"ПОДОБНО\" указано поле таблицы.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "380", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Длина индекса составляет больше 900 байт.", +"Description": "

      Общие требования к конфигурации

      #std467

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

      \n\n\n\n
      \n
      \n

      Область применения (уточнение): управляемое приложение, обычное приложение.

      \n

      1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
      Дополнительные материалы:

      \n\n

      1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

      \n\n

      1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

      \n
        \n
      • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
      • придерживаться общей схемы установки признаков общих модулей, \n
      • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
      \n

      Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

      \n

      1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

      \n

      2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

      \n

      2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

      \n

      2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

      \n

      Исключение составляют:

      \n
        \n
      • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
      • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "381", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Длина имени объекта метаданных превышает 80 символов.", +"Description": "

      Имя, синоним, комментарий

      #std474

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

      \n

      Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

      \n

      1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

      \n

      1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

      \n

      В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
      Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
      правильно: «Загрузка данных из Microsoft Excel».

      \n

      1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

      \n

      1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
      неправильно

      \n
        \n
      • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
      \n

      правильно

      \n
        \n
      • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
      \n

      Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

      \n
      \n

      См. также: Пользовательские представления объектов, Тексты

      \n

      1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

      \n

      Например, неправильно давать справочникам следующие синонимы:

      \n
        \n
      • Банковские счета, \n
      • Банковские счета контрагентов
      \n

      правильно:

      \n
        \n
      • Банковские счета организаций, \n
      • и Банковские счета контрагентов
      \n

      Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

      \n

      Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
      Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
      Неправильно:

      \n
        \n
      • Количество \n
      • Количество (по учету)
      \n

      правильно:

      \n
        \n
      • Количество (в наличии) \n
      • Количество (по учету)
      \n

      Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
      Неправильно:

      \n
        \n
      • Наименование \n
      • Полное наименование
      \n

      правильно:

      \n
        \n
      • Рабочее наименование \n
      • Наименование для печати
      \n

      2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
      Например, неправильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
      \n

      правильно:

      \n
        \n
      • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
      • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
      \n

      Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

      \n
        \n
      • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
      • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
      • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
      \n

      Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

      \n

      А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

      \n

      Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

      \n
      \n

      См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

      \n

      2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

      \n

      Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

      \n

      2.3. Имена объектов метаданных не должны превышать 80 символов.

      \n

      2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

      \n

      2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

      \n

      ВЫБРАТЬ
      Сведения.Сведения
      ИЗ
      РегистрСведений.Сведения КАК Сведения

      \n

      3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

      \n

      3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

      4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "384", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Установлено нулевое поле у табличного документа", +"Description": "

      Формирование печатных форм

      #std548

      Область применения: управляемое приложение.

      \n

      Некоторые справочники, документы и др. объекты конфигурации могут предоставлять команды по выводу их на печать. В данной статье приведены требования к реализации таких команд.

      \n

      1.1. Для формирования печатной формы пользователю должно быть достаточно прав:

      \n
        \n
      • на чтение основных объектов метаданных, по данным которых формируется печатная форма (например, для формирования печатной формы документа ЗаказПокупателя нужны права на чтение этого документа); \n
      • и на выполнение команды, которая инициирует формирование печатной формы (если у пользователя есть права на документ ЗаказПокупателя, то в общем случае, это не приводит к тому, что ему автоматически становятся доступны все печатные формы; права на печатные формы могут быть ограничены отдельно с помощью прав на команды).
      \n

      1.2. Если в печатную форму дополнительно выводятся данные каких-либо других объектов, связанных с основными, то права на них не должны оказывать влияния на возможность формирования печатной формы, а также на состав выводимой на печать информации. Поэтому код формирования печатной формы следует выполнять в таком случае в привилегированном режиме.

      \n

      Например, для формирования печатной формы «Счет-фактура (в валюте)» используются данные документа, на основе которого формируется счет-фактура, и данные регистра сведений «Курсы валют». Пользователь может сформировать печатную форму, если у него есть права на чтение документа и на выполнение команды печати. Но при этом не имеет значения, есть ли у него права на регистр сведений «Курсы валют».

      \n
      \n

      См. также: Использование привилегированного режима

      \n

      2. Если функция печати предполагает множественную печать нескольких объектов, то по соображениям производительности (снижение нагрузки на СУБД) необходимо выполнять выборку данных в одном запросе, результаты которого затем обходятся в цикле.

      \n
      \n

      См. также: Многократное выполнение однотипных запросов

      \n

      Исключение из этого правила могут составлять случаи, когда выборка данных для нескольких объектов в одном запросе

      \n
        \n
      • заметно усложняет разработку самого запроса \n
      • наоборот, может привести к деградации производительности. Например, когда запрос содержит обращение к виртуальным таблицам, формируемым на определенную дату (как в случае с виртуальными таблицами остатков регистра накопления, срезом последних периодического регистра сведений и т.п.).
      \n

      3.1. Печатная и экранная формы объектов (справочников, документов и др.), в которых выводятся табличные части, должны соответствовать друг другу по составу и порядку строк табличных частей. В частности, при выводе на печать не следует каким-либо образом дополнительно группировать строки табличных частей.

      \n

      3.2. Однако, если строки в экранной форме уже сгруппированы по каким-либо признакам, то при выводе на печать следует применять такую же группировку.

      \n

      Например, рассмотрим печатную и экранную формы документа, в которых выводится табличная часть цен номенклатуры по типам цен: для каждой номенклатуры в колонках выводятся розничная, оптовая и другие типы цен, но при этом «физически» одна строка табличной части документа содержит информацию о цене только одного типа. 

      \n

      4.1. В табличных частях печатных форм следует всегда выводить колонку со значением реквизита «Номер строки». В этом случае пользователи всегда смогут легко сопоставить строки табличных частей в печатных и экранных формах.

      \n

      4.2. В тех случаях, когда на экранной форме не отображается реквизит «Номер строки», строки в печатной форме нумеруются в порядке их вывода.

      \n

      4.3. Заголовок колонки с номером строки зависит от прикладной специфики печатной формы и может различаться в разных печатных формах. Например, в ТОРГ-12 колонка имеет строго регламентированное название «Номер по порядку», а в нерегламентированных печатных формах – может называться «№».

      \n

      5. Строки табличных частей следует выводить в печатных формах отсортированными по полю «Номер строки», поскольку порядок вывода может быть разным на различных СУБД.

      \n

      Исключение могут составлять печатные формы, прикладная специфика которых требует сортировки по другому реквизиту. Например, в задании кладовщику на отбор товаров из складских ячеек, строки задания отсортированы по порядку обхода ячеек склада (при этом значение реквизита «Номер строки» также выводится в соответствующей колонке).

      \n
      \n

      См. также: Упорядочивание результатов запроса

      \n

      6.1. При выводе данных в печатные формы, необходимо обеспечить, чтобы они были выведены полностью и не обрезались.

      \n\n\n\n
      \n

      Методическая рекомендация (полезный совет)

      \n

      6.2. В случае если печатные формы формируются с помощью табличных макетов, то при выводе строк табличных частей рекомендуется устанавливать свойство АвтоВысотаСтроки (объекта ОбластьЯчеекТабличногоДокумента) в значение Истина. Это позволяет избежать обрезания длинных текстовых строк, когда ширины колонок таблиц недостаточно.

      \n

      7. При подготовке табличного документа на сервере не следует устанавливать размер полей заведомо меньше физических ограничений полей у принтера. В частности, недопустимо устанавливать нулевые поля.

      \n

      В общем случае, размер полей табличного документа рекомендуется не менять (оставлять по умолчанию), кроме тех случаев, когда они явно регламентированы или стандартизированы. Например, согласно ГОСТ Р 6.30-2003 \"Унифицированные системы документации. Унифицированная система организационно-распорядительной документации. Требования к оформлению документов\" в документе должны быть заданы поля: 20 мм левое, 10 мм правое, 20 мм верхнее, 20 мм нижнее.

      \n

      Требование обусловлено тем, что получение физических ограничений полей клиентского принтера не представляется возможным на сервере приложений, в связи с чем, при печати документа с нулевыми полями текст, выступающий за минимально допустимые поля принтера, не будет напечатан.

      \n

      Пример некорректного кода:

      \n

      // Зададим параметры печатной формы по умолчанию
      ТабДокумент.ПолеСверху              = 0;
      ТабДокумент.ПолеСлева               = 0;
      ТабДокумент.ПолеСнизу               = 0;
      ТабДокумент.ПолеСправа              = 0;

      \n

      8. Если в конфигурации предусмотрена возможность того, что макет печатной формы может быть отредактирован пользователем в режиме предприятия (например, средствами подсистемы «Печать» Библиотеки стандартных подсистем), то необходимо рассчитывать на то, что любые параметры в нем могут быть изменены или удалены. Поэтому для повышения устойчивости кода формирования печатной формы следует избегать явного присвоения значений параметров в областях печати. Вместо этого следует использовать глобальный метод ЗаполнитьЗначенияСвойств или метод Заполнить коллекции ПараметрыМакетаТекстовогоДокумента.

      \n

      Неправильно:

      \n

      ОбластьПечати.Параметры.Организация = ДанныеПечати.Организация; // будет ошибка при отсутсвии в макете параметра Организация
      ОбластьПечати.Параметры.Контрагент = ДанныеПечати.Контрагент;

      \n


      Правильно:

      \n

      ЗаполнитьЗначенияСвойств(ОбластьПечати.Параметры, ДанныеПечати);

      \n

      или

      \n

      ОбластьПечати.Параметры.Заполнить(ДанныеПечати);

      \n

      Примечание: в переменной ДанныеПечати в примерах может быть Структура, Соответствие, ВыборкаИзРезультатаЗапроса или любая другая коллекция со значениями параметров.

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "386", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В свойствах формы настроено условное оформление.", +"Description": "

      Условное оформление в формах

      #std710

      Область применения: управляемое приложение.

      \n

      Рекомендация (полезный совет)

      \n

      1. Для настройки некоторых свойств элементов управления можно использовать условное оформление. Однако у этого механизма также есть ряд ограничений.

      \n

      1.1. Не следует использовать условное оформление для скрытия в таблице строк целиком. Это существенно замедляет работу в веб-клиенте, а также приводит к некорректному отображению содержимого таблицы.

      1.2. Если задача может быть функционально решена как с помощью условного оформления динамического списка, так и с помощью условного оформления формы, то следует выбрать первый вариант (условное оформление динамического списка). Это также несколько ускорит открытие формы. \n

      2.1. Настройку условного оформления форм и динамических списков рекомендуется делать в коде формы. Такой подход имеет ряд преимуществ перед заданием настроек условного оформления в свойствах формы:

      \n
        \n
      • настройки однотипного условного оформления можно вынести в общие модули. Например, есть 80 форм, имеющих условное оформление:
        \"если НЕ ХарактеристикиИспользуются, то в поле \"Характеристика\" вывести текст <характеристики не используются>\",
        то можно вынести эту настройку в код процедуры общего модуля; \n
      • при объединении конфигураций есть возможность объединять условное оформление (особенно это актуально при разветвленной разработке конфигураций); \n
      • при изменении в метаданных (например, переименовании значения перечисления) условное оформление может перестать работать. Если условное оформление настраивается в коде конфигурации, то при синтаксическом контроле модулей эта ошибка будет выявлена. Так ошибки в настройках условного оформления будут выявляться средствами автоматизированной проверки (например, АПК), т.к. будет диагностироваться ошибка при попытке получения формы.
      \n

      2.2. Все настройки условного оформления должны производится при создании формы и потом не должны модифицироваться. Исключением могут являться случаи, когда элементы формы генерируются программно – условное оформление таких элементов нужно настраивать при генерации элементов и потом не нужно менять.

      \n

      2.3. В коде процедуры установки условного оформления нужно минимизировать использование строковых констант, а использовать переменные, разыменования и т.д. – такой подход позволит минимизировать количество скрытых ошибок в настройках условного оформления, например:

      \n

      &НаСервере
      Процедура УстановитьУсловноеОформление()
       
       УсловноеОформление.Элементы.Очистить();
       
       Элемент = УсловноеОформление.Элементы.Добавить();

      \n

       ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
       ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ТоварыУпаковка.Имя);

      \n

       ГруппаОтбора1 = Элемент.Отбор.Элементы.Добавить(Тип(\"ГруппаЭлементовОтбораКомпоновкиДанных\"));
       ГруппаОтбора1.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"АдресноеХранение\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
       ОтборЭлемента.ПравоеЗначение = Ложь;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"Объект.Товары.ТипНоменклатуры\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
       ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыНоменклатуры.Товар;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"Объект.Статус\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
       ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПриходныхОрдеров.КПоступлению;

      \n

       Элемент.Оформление.УстановитьЗначениеПараметра(\"ОтметкаНезаполненного\", Ложь);

      \n

      КонецПроцедуры

      \n

      См. также

      \n
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "387", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В свойствах динамического списка настроено условное оформление.", +"Description": "

      Условное оформление в формах

      #std710

      Область применения: управляемое приложение.

      \n

      Рекомендация (полезный совет)

      \n

      1. Для настройки некоторых свойств элементов управления можно использовать условное оформление. Однако у этого механизма также есть ряд ограничений.

      \n

      1.1. Не следует использовать условное оформление для скрытия в таблице строк целиком. Это существенно замедляет работу в веб-клиенте, а также приводит к некорректному отображению содержимого таблицы.

      1.2. Если задача может быть функционально решена как с помощью условного оформления динамического списка, так и с помощью условного оформления формы, то следует выбрать первый вариант (условное оформление динамического списка). Это также несколько ускорит открытие формы. \n

      2.1. Настройку условного оформления форм и динамических списков рекомендуется делать в коде формы. Такой подход имеет ряд преимуществ перед заданием настроек условного оформления в свойствах формы:

      \n
        \n
      • настройки однотипного условного оформления можно вынести в общие модули. Например, есть 80 форм, имеющих условное оформление:
        \"если НЕ ХарактеристикиИспользуются, то в поле \"Характеристика\" вывести текст <характеристики не используются>\",
        то можно вынести эту настройку в код процедуры общего модуля; \n
      • при объединении конфигураций есть возможность объединять условное оформление (особенно это актуально при разветвленной разработке конфигураций); \n
      • при изменении в метаданных (например, переименовании значения перечисления) условное оформление может перестать работать. Если условное оформление настраивается в коде конфигурации, то при синтаксическом контроле модулей эта ошибка будет выявлена. Так ошибки в настройках условного оформления будут выявляться средствами автоматизированной проверки (например, АПК), т.к. будет диагностироваться ошибка при попытке получения формы.
      \n

      2.2. Все настройки условного оформления должны производится при создании формы и потом не должны модифицироваться. Исключением могут являться случаи, когда элементы формы генерируются программно – условное оформление таких элементов нужно настраивать при генерации элементов и потом не нужно менять.

      \n

      2.3. В коде процедуры установки условного оформления нужно минимизировать использование строковых констант, а использовать переменные, разыменования и т.д. – такой подход позволит минимизировать количество скрытых ошибок в настройках условного оформления, например:

      \n

      &НаСервере
      Процедура УстановитьУсловноеОформление()
       
       УсловноеОформление.Элементы.Очистить();
       
       Элемент = УсловноеОформление.Элементы.Добавить();

      \n

       ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
       ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ТоварыУпаковка.Имя);

      \n

       ГруппаОтбора1 = Элемент.Отбор.Элементы.Добавить(Тип(\"ГруппаЭлементовОтбораКомпоновкиДанных\"));
       ГруппаОтбора1.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"АдресноеХранение\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
       ОтборЭлемента.ПравоеЗначение = Ложь;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"Объект.Товары.ТипНоменклатуры\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
       ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыНоменклатуры.Товар;

      \n

       ОтборЭлемента = ГруппаОтбора1.Элементы.Добавить(Тип(\"ЭлементОтбораКомпоновкиДанных\"));
       ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(\"Объект.Статус\");
       ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
       ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПриходныхОрдеров.КПоступлению;

      \n

       Элемент.Оформление.УстановитьЗначениеПараметра(\"ОтметкаНезаполненного\", Ложь);

      \n

      КонецПроцедуры

      \n

      См. также

      \n
      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "388", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неэкспортная процедура (функция) в разделе \"ПрограммныйИнтерфейс\".", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "389", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неэкспортная процедура (функция) в разделе \"СлужебныйПрограммныйИнтерфейс\".", +"Description": "

      Описание процедур и функций

      #std453

      Область применения: управляемое приложение, мобильное приложение, обычное приложение.

      \n

      1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

      \n

      При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

      \n

      При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

      \n

      2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

      \n
      \n

      См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

      \n

      3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

      \n

      Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

      \n

      4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
      Например, неправильно:

      // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
      \n

      В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

      // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
      \n

      Этот комментарий не дает никакой дополнительной информации о функции.

      \n

      5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

      5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

      \n

      Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

      \n

      Например, неправильно:

      // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      Правильно:

      // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
      \n

      5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

      \n

      5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

      \n

      Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

      \n

      Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
      Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

      \n

      Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

      \n

      Например, неправильно:

      // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
      \n

      Правильно:

      // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
      \n

      Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

      \n

      Например, неправильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Строка - Строка - строка, содержащая электронные адреса
      //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      Правильно:

      \n

      // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
      //
      // Параметры:
      //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
      //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
      //
      Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

      \n

      В данном примере текстовое описание для параметра «Адреса» нужно чтобы

      \n
        \n
      • указать правило передачи нескольких адресов (через зяпятую) \n
      • привести пример
      \n

      Текстовое описание для параметра «Задача» не нужно.

      \n

      5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
      Например:

      // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
      \n

      5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

      \n

      Например, неправильно:

      // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
      // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
      \n

      Правильно:

      // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

      // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
      \n

      В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

      // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
      \n

      5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
      Например:

      // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
      \n

      5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

      \n

      Например:

      //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
      \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
      \n

      5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

      // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
      \n

      Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

      \n

      Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

      \n

      5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
      Например, неправильно:

      // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
      \n

      Правильно:

      // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
      \n

      5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

      // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
      \n

      5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

      \n

      Например:

      // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
      \n

      5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
      Например:

      // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
      \n

      5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
      Например:

      // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
      \n

      6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
      директиву компиляции. Например:

      // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
      \n

      Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

      \n

      7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

      \n

      Примеры описания процедур и функций

      \n

      Пример описания функции с одним параметром:

      // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
      \n

      Пример описания процедуры без параметров:

      // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
       
      \n\n\n\n
      \n

      Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

      \n

      Для этого необходимо:

      \n
        \n
      1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
      2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
      3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
      ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "392", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Кнопка по умолчанию на командной панели формы не является самой левой (первой).", +"Description": "

      Командная панель формы

      #std620

      Область применения: управляемое приложение.

      \n

      См. также: Командная панель документа (8.3)

      \n

      В командной панели формы кнопка по умолчанию должна быть самой левой (первой)

      \n

       

      ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "393", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка просмотра для реквизита формы.", +"Description": "

      Проверка прав доступа

      #std737

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

      \n
        \n
      • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
      • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
      \n

      Эти меры позволяют:

      \n
        \n
      • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
      • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
      • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
      \n

      2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

      \n

      3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
      Например, неправильно:

      \n

      Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
      Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

      \n

      правильно:

      \n

      Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
      Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

      \n

      Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

      \n

      4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
      Например, без использования БСП:

      \n

      Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

      \n

      Либо аналогичная проверка с использованием БСП:

      \n

      Если Пользователи.РолиДоступны(...) Тогда ...

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "394", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка редактирования для реквизита формы.", +"Description": "

      Проверка прав доступа

      #std737

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

      \n
        \n
      • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
      • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
      \n

      Эти меры позволяют:

      \n
        \n
      • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
      • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
      • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
      \n

      2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

      \n

      3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
      Например, неправильно:

      \n

      Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
      Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

      \n

      правильно:

      \n

      Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
      Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

      \n

      Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

      \n

      4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
      Например, без использования БСП:

      \n

      Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

      \n

      Либо аналогичная проверка с использованием БСП:

      \n

      Если Пользователи.РолиДоступны(...) Тогда ...

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "395", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка использования для команды формы.", +"Description": "

      Проверка прав доступа

      #std737

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

      \n
        \n
      • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
      • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
      \n

      Эти меры позволяют:

      \n
        \n
      • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
      • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
      • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
      \n

      2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

      \n

      3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
      Например, неправильно:

      \n

      Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
      Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

      \n

      правильно:

      \n

      Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
      Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

      \n

      Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

      \n

      4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
      Например, без использования БСП:

      \n

      Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

      \n

      Либо аналогичная проверка с использованием БСП:

      \n

      Если Пользователи.РолиДоступны(...) Тогда ...

      \n

      См. также

      \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "397", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не задан таймаут для объекта при работе с внешними ресурсами.", +"Description": "

      Таймауты при работе с внешними ресурсами

      #std748

      Область применения: управляемое приложение, обычное приложение.

      \n

      1. При работе с внешними ресурсами с помощью объектов WSОпределения, WSПрокси, HTTPСоединение, FTPСоединение, ИнтернетПочтовыйПрофиль следует задавать таймаут – предельное время  ожидания выполнения операции. В противном случае, в результате бесконечного ожидания программа зависнет или часть функционала программы станет недоступна.

      \n

      Установка таймаута является защитой от целого ряда внешних факторов:

      \n
        \n
      • нестабильного подключения к Интернету, когда регулярно происходит прерывание связи, и система не может получить цельный ответ сервера, к которому выполняется подключение; \n
      • при включенных антивирусных программах или при неправильных настройках брандмауэра; \n
      • неправильной настройки прокси-сервера; \n
      • ненадежной работы веб-сервера из-за возросшей нагрузки или некорректной работы скриптов.
      \n

      \n

      Например, при получении описания веб-сервиса и вызове его операций – если удаленная сторона долго не отвечает (например, выключена, находится на обслуживании или возникли временные неполадки), ожидание ответа может длиться бесконечно. Поэтому если веб-сервис был вызван в результате интерактивных действий пользователя, то внешне будет выглядеть так, что «программа зависла»; а если веб-сервис вызывается из регламентного задания, то связанная с ним часть функционала программы может стать недоступна.

      \n

      \n

      2. В общем виде, время выполнения операции с внешними ресурсами складывается из шести этапов:

      \n
        \n
      • DNS Lookup — время, потраченное на определение IP адреса по доменному имени (если применимо); \n
      • Connect — установка соединения с веб-сервером по полученному IP-адресу; \n
      • Send — отправка данных на веб-сервер; \n
      • Wait — ждем, пока данные дойдут до веб-сервера и он их обработает; \n
      • Receive — получение ответа от веб-сервера; \n
      • Cache Read – получение данных от веб-сервера.
      \n

      Например, при таймауте в 60 секунд программа и вызываемый внешний ресурс должны успеть выполнить шесть выше перечисленных этапов операции, иначе соединение будет разорвано, а передача данных прервана. Однако если в процессе выполнения операции возникнет сбой, то система и/или пользователь будет зря ожидать 60 секунд.

      \n

      Поэтому величину таймаута рекомендуется определять, исходя из ожидаемого времени выполнения конкретной операции:

      \n
        \n
      • Для быстрых операций (например, проверка доступности сервера) величина таймаута должна выбираться, соответственно, небольшой; \n
      • В общем случае, не следует выбирать таймаут более 3 минут, чтобы при недоступности удаленной стороны не допустить эффект «зависания» программы; \n
      • Но если операция выполняется долго из-за этапов Send или Cache Read, т.е. это передача больших объемов данных на веб-сервер или загрузка большого файла с внешнего ресурса, то следует устанавливать большой таймаут, исходя из оценки объема передаваемых данных, но не более 12 часов.
      \n

      Подобнее о рекомендуемых величинах таймаута для различных операций см. в таблице п. 4.

      \n

      3. Рекомендации по снижению величин таймаута и повышению отзывчивости программы при работе с внешними ресурсами.

      \n

      3.1. При разработке веб-сервисов, на операции которых предусмотрен таймаут более 20 секунд (ориентировочно), рекомендуется:

      \n
        \n
      • предусмотреть в веб-сервисе отдельную контрольную операцию Ping; \n
      • при работе с этим веб-сервисом, предварительно получать для нее прокси с небольшим таймаутом в 7 секунд и вызывать контрольную операцию Ping; \n
      • только после этого получать основной прокси.
      \n

      Пример вызова веб-сервиса.

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Неправильно\n

      Правильно

      \n

      Реализация модуля веб-сервиса PingPong:

      \n

      Функция Pong(Знач Параметр)
        Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Привет, %1'\"), Параметр);
      КонецФункции

      \n

      Функция Ping()
        Возврат Истина; // Проверка связи
      КонецФункции

      \n

      Функция Pong(Знач Параметр)
        Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Привет, %1'\"), Параметр);
      КонецФункции

      \n

      Реализация вызывающей стороны (без использования Библиотеки стандартных подсистем):

      \n

      // Ждем не более минуты
      PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60);
      Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

      \n

      // Ждем не более 3 секунд
      PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 3);
      PingPong.Ping(); // проверка связи

      \n

      // Сервис жив, далее работаем с ним и ждем не более минуты
      PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60); 
      Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

      \n

      \n

      При использовании Библиотеки стандартных подсистем:

      \n
        \n
      • для работы с веб-сервисами предназначена функция WSПрокси общего модуля ОбщегоНазначения (включает в себя поддержку контрольной операции Ping); \n
      • для получения данных по протоколам HTTP(S) и FTP(S) – подсистема «Получение файлов через Интернет».
      \n

      Пример реализации вызывающей стороны с использованием Библиотеки стандартных подсистем:

      \n

      // Сделать контрольный вызов Ping и ждать не более минуты на дальнейших операциях.
      PingPong = ОбщегоНазначения.WSПрокси(АдресВебСервиса,..., 60, Истина);
      // Сервис точно жив, далее работаем с ним.
      Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

      \n

      3.2. Для других видов внешних ресурсов (не веб-сервисов) рекомендуется применять аналоги операции Ping. Например:

      \n
        \n
      • для сервисов, работающих через REST API – это контрольная отправка тестовой команды; в большинстве случаев, если ответ с кодом 200, то сервис работает; \n
      • для FTP/WebDAV-ресурсов – это контрольная загрузка (отправка) файла-пустышки.
      \n

      3.3. Веб-сервисы, операции, которых занимают объективно много времени из-за этапа Wait (т.е. долго отрабатывает само веб-приложение), и они не могут быть ускорены (оптимизированы) по объективным причинам, следует переводить на асинхронный режим выполнения:

      \n
        \n
      • запускать фоновое задание для выполнения подобной «тяжелой» операции, \n
      • и предусмотреть дополнительные операции по проверке готовности и получению результата.
      \n

      Пример асинхронного вызова веб-сервиса.

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Неправильно\n

      Правильно

      \n

      Реализация модуля веб-сервиса Long:

      \n

      Функция GetData()
          Результат = <очень длительные вычисления>;
          Возврат Результат;
      КонецФункции

      \n

      Функция StartDoLong()
          // запуск фонового задания
          ИдентификаторОперации = ...
          // возвращаем идентификатор операции для отслеживания ее готовности
          Возврат ИдентификаторОперации;
      КонецФункции

      \n

      Функция IsReady(Знач ИдентификаторОперации)
          // проверяем, завершено ли фоновое задание по переданному идентификатору
          Готовность = ...
          Возврат Готовность;
      КонецФункции

      \n

      Функция GetData(Знач ИдентификаторОперации)
          Результат = <получаем уже готовый результат по переданному идентификатору >;
          Возврат Результат;
      КонецФункции

      \n

      Реализация вызывающей стороны:

      \n

      Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 1 час

      Результат = Long.GetData();

      \n

      Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 1 час

      ИдентификаторОперации = Long.StartDoLong();

      Пока Не Long.IsReady(ИдентификаторОперации) Цикл
          <ждем определенный интервал времени>
      КонецЦикла;
      Результат = Long.GetData(ИдентификаторОперации);

      * это лишь упрощенная схема реализации вызывающей стороны; в действительности,
      код вызывающей стороны также должен быть реализован асинхронно с помощью включения
      регламентного задания, либо периодического обработчика ожидания на клиенте,
      который проверяет готовность и получает результат.

      \n

      4. Рекомендуемые величины таймаутов для различных операций:

      \n

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      Операция Таймаут (секунд)
      Получение описания веб-сервиса 7
      Проверка корректности введенного адреса, взаимодействие с менеджером сервиса в модели сервиса и прочие «быстрые» операции10-20
      Получение сведений об одном контрагенте, обмен сообщениями, отправка SMS, удаленное администрирование ИБ в модели сервиса60-1201
      Передача сообщений обмена данными через веб-сервис или получение файлов из внешнего ресурса до 1 Мб.120-1801
      Загрузка файлов более 1 МбЕсли известен размер файла, то размер в мегабайтах * 1282, иначе предельное время загрузки, но не более 43200 3

      \n
      \n\n

      1 Следует вызывать только после контрольной операции Ping.

      \n

      2 Загрузка 1 мегабайта данных занимает 128 секунд, при скорости 64 кбит/с, т.к. сотовые операторы в определенных случаях ограничивают скорость загрузки этой величиной.

      \n

      3 Таймаут продолжительностью 43200(12 часов) сек. является компромиссным решением, т.к. в случае нештатной ситуации процесс «отвиснет» на следующее утро и вернет управление, в отличие от полностью зависнувшей программы при неустановленном таймауте.

      \n
        \n
          ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "398", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Задан нулевой таймаут для объекта при работе с внешними ресурсами.", +"Description": "

          Таймауты при работе с внешними ресурсами

          #std748

          Область применения: управляемое приложение, обычное приложение.

          \n

          1. При работе с внешними ресурсами с помощью объектов WSОпределения, WSПрокси, HTTPСоединение, FTPСоединение, ИнтернетПочтовыйПрофиль следует задавать таймаут – предельное время  ожидания выполнения операции. В противном случае, в результате бесконечного ожидания программа зависнет или часть функционала программы станет недоступна.

          \n

          Установка таймаута является защитой от целого ряда внешних факторов:

          \n
            \n
          • нестабильного подключения к Интернету, когда регулярно происходит прерывание связи, и система не может получить цельный ответ сервера, к которому выполняется подключение; \n
          • при включенных антивирусных программах или при неправильных настройках брандмауэра; \n
          • неправильной настройки прокси-сервера; \n
          • ненадежной работы веб-сервера из-за возросшей нагрузки или некорректной работы скриптов.
          \n

          \n

          Например, при получении описания веб-сервиса и вызове его операций – если удаленная сторона долго не отвечает (например, выключена, находится на обслуживании или возникли временные неполадки), ожидание ответа может длиться бесконечно. Поэтому если веб-сервис был вызван в результате интерактивных действий пользователя, то внешне будет выглядеть так, что «программа зависла»; а если веб-сервис вызывается из регламентного задания, то связанная с ним часть функционала программы может стать недоступна.

          \n

          \n

          2. В общем виде, время выполнения операции с внешними ресурсами складывается из шести этапов:

          \n
            \n
          • DNS Lookup — время, потраченное на определение IP адреса по доменному имени (если применимо); \n
          • Connect — установка соединения с веб-сервером по полученному IP-адресу; \n
          • Send — отправка данных на веб-сервер; \n
          • Wait — ждем, пока данные дойдут до веб-сервера и он их обработает; \n
          • Receive — получение ответа от веб-сервера; \n
          • Cache Read – получение данных от веб-сервера.
          \n

          Например, при таймауте в 60 секунд программа и вызываемый внешний ресурс должны успеть выполнить шесть выше перечисленных этапов операции, иначе соединение будет разорвано, а передача данных прервана. Однако если в процессе выполнения операции возникнет сбой, то система и/или пользователь будет зря ожидать 60 секунд.

          \n

          Поэтому величину таймаута рекомендуется определять, исходя из ожидаемого времени выполнения конкретной операции:

          \n
            \n
          • Для быстрых операций (например, проверка доступности сервера) величина таймаута должна выбираться, соответственно, небольшой; \n
          • В общем случае, не следует выбирать таймаут более 3 минут, чтобы при недоступности удаленной стороны не допустить эффект «зависания» программы; \n
          • Но если операция выполняется долго из-за этапов Send или Cache Read, т.е. это передача больших объемов данных на веб-сервер или загрузка большого файла с внешнего ресурса, то следует устанавливать большой таймаут, исходя из оценки объема передаваемых данных, но не более 12 часов.
          \n

          Подобнее о рекомендуемых величинах таймаута для различных операций см. в таблице п. 4.

          \n

          3. Рекомендации по снижению величин таймаута и повышению отзывчивости программы при работе с внешними ресурсами.

          \n

          3.1. При разработке веб-сервисов, на операции которых предусмотрен таймаут более 20 секунд (ориентировочно), рекомендуется:

          \n
            \n
          • предусмотреть в веб-сервисе отдельную контрольную операцию Ping; \n
          • при работе с этим веб-сервисом, предварительно получать для нее прокси с небольшим таймаутом в 7 секунд и вызывать контрольную операцию Ping; \n
          • только после этого получать основной прокси.
          \n

          Пример вызова веб-сервиса.

          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
          Неправильно\n

          Правильно

          \n

          Реализация модуля веб-сервиса PingPong:

          \n

          Функция Pong(Знач Параметр)
            Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Привет, %1'\"), Параметр);
          КонецФункции

          \n

          Функция Ping()
            Возврат Истина; // Проверка связи
          КонецФункции

          \n

          Функция Pong(Знач Параметр)
            Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Привет, %1'\"), Параметр);
          КонецФункции

          \n

          Реализация вызывающей стороны (без использования Библиотеки стандартных подсистем):

          \n

          // Ждем не более минуты
          PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60);
          Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

          \n

          // Ждем не более 3 секунд
          PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 3);
          PingPong.Ping(); // проверка связи

          \n

          // Сервис жив, далее работаем с ним и ждем не более минуты
          PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60); 
          Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

          \n

          \n

          При использовании Библиотеки стандартных подсистем:

          \n
            \n
          • для работы с веб-сервисами предназначена функция WSПрокси общего модуля ОбщегоНазначения (включает в себя поддержку контрольной операции Ping); \n
          • для получения данных по протоколам HTTP(S) и FTP(S) – подсистема «Получение файлов через Интернет».
          \n

          Пример реализации вызывающей стороны с использованием Библиотеки стандартных подсистем:

          \n

          // Сделать контрольный вызов Ping и ждать не более минуты на дальнейших операциях.
          PingPong = ОбщегоНазначения.WSПрокси(АдресВебСервиса,..., 60, Истина);
          // Сервис точно жив, далее работаем с ним.
          Результат = PingPong.Pong(НСтр(\"ru = 'Мяч'\"));

          \n

          3.2. Для других видов внешних ресурсов (не веб-сервисов) рекомендуется применять аналоги операции Ping. Например:

          \n
            \n
          • для сервисов, работающих через REST API – это контрольная отправка тестовой команды; в большинстве случаев, если ответ с кодом 200, то сервис работает; \n
          • для FTP/WebDAV-ресурсов – это контрольная загрузка (отправка) файла-пустышки.
          \n

          3.3. Веб-сервисы, операции, которых занимают объективно много времени из-за этапа Wait (т.е. долго отрабатывает само веб-приложение), и они не могут быть ускорены (оптимизированы) по объективным причинам, следует переводить на асинхронный режим выполнения:

          \n
            \n
          • запускать фоновое задание для выполнения подобной «тяжелой» операции, \n
          • и предусмотреть дополнительные операции по проверке готовности и получению результата.
          \n

          Пример асинхронного вызова веб-сервиса.

          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
          Неправильно\n

          Правильно

          \n

          Реализация модуля веб-сервиса Long:

          \n

          Функция GetData()
              Результат = <очень длительные вычисления>;
              Возврат Результат;
          КонецФункции

          \n

          Функция StartDoLong()
              // запуск фонового задания
              ИдентификаторОперации = ...
              // возвращаем идентификатор операции для отслеживания ее готовности
              Возврат ИдентификаторОперации;
          КонецФункции

          \n

          Функция IsReady(Знач ИдентификаторОперации)
              // проверяем, завершено ли фоновое задание по переданному идентификатору
              Готовность = ...
              Возврат Готовность;
          КонецФункции

          \n

          Функция GetData(Знач ИдентификаторОперации)
              Результат = <получаем уже готовый результат по переданному идентификатору >;
              Возврат Результат;
          КонецФункции

          \n

          Реализация вызывающей стороны:

          \n

          Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 1 час

          Результат = Long.GetData();

          \n

          Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 1 час

          ИдентификаторОперации = Long.StartDoLong();

          Пока Не Long.IsReady(ИдентификаторОперации) Цикл
              <ждем определенный интервал времени>
          КонецЦикла;
          Результат = Long.GetData(ИдентификаторОперации);

          * это лишь упрощенная схема реализации вызывающей стороны; в действительности,
          код вызывающей стороны также должен быть реализован асинхронно с помощью включения
          регламентного задания, либо периодического обработчика ожидания на клиенте,
          который проверяет готовность и получает результат.

          \n

          4. Рекомендуемые величины таймаутов для различных операций:

          \n

          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
          Операция Таймаут (секунд)
          Получение описания веб-сервиса 7
          Проверка корректности введенного адреса, взаимодействие с менеджером сервиса в модели сервиса и прочие «быстрые» операции10-20
          Получение сведений об одном контрагенте, обмен сообщениями, отправка SMS, удаленное администрирование ИБ в модели сервиса60-1201
          Передача сообщений обмена данными через веб-сервис или получение файлов из внешнего ресурса до 1 Мб.120-1801
          Загрузка файлов более 1 МбЕсли известен размер файла, то размер в мегабайтах * 1282, иначе предельное время загрузки, но не более 43200 3

          \n
          \n\n

          1 Следует вызывать только после контрольной операции Ping.

          \n

          2 Загрузка 1 мегабайта данных занимает 128 секунд, при скорости 64 кбит/с, т.к. сотовые операторы в определенных случаях ограничивают скорость загрузки этой величиной.

          \n

          3 Таймаут продолжительностью 43200(12 часов) сек. является компромиссным решением, т.к. в случае нештатной ситуации процесс «отвиснет» на следующее утро и вернет управление, в отличие от полностью зависнувшей программы при неустановленном таймауте.

          \n
            \n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "399", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует или неверно описана секция \"Параметры\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "400", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует или неверно описана секция \"Возвращаемое значение\" в комментарии к экспортной функции.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "401", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не описаны некоторые параметры в секции \"Параметры\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "402", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Секция \"Возвращаемое значение\" находится перед секцией \"Параметры\" в комментарии к экспортной функции.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "403", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Некорректно оформлена гиперссылка \"См. ...\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "404", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не найден объект переадресации из гиперссылки \"См. ...\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "405", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Описаны лишние параметры в секции \"Параметры\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "406", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Некорректно описаны некоторые параметры в секции \"Параметры\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "407", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Некорректно описан тип некоторых параметров в секции \"Параметры\" в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "408", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Описание параметров в секции \"Параметры\" должно начинаться с новой строки в комментарии к экспортной процедуре (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "409", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Описание возвращаемого значения в секции \"Возвращаемое значение\" должно начинаться с новой строки в комментарии к экспортной функции.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "410", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Описана секция \"Параметры\" в комментарии к экспортной процедуре (функции), не имеющей параметров.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "412", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Значение свойства \"История выбора при вводе\" у документа не равно \"Не использовать\".", +"Description": "

              История выбора при вводе

              #std744

              Область применения: управляемое приложение.

              \n

              1. Для свойства История выбора  большинства объектов метаданных должно быть установлено значение Авто.

              \n

              2.1. Историю выбора в свойствах объекта метаданных рекомендуется отключать, если ее использование не соответствует прикладной логике конфигурации:

              \n
              \n

              • для объектов, сценарий использования которых не предполагает повторный выбор из 5 ранее выбранных вариантов. 

              \n

              Примеры:

              \n
              \n

              Специфика использования большинства документов такова, что повторный их выбор маловероятен, например, выбор объекта расчетов в Поступлении безналичных денежных средств.

              \n

              • для объектов, в модуле менеджера которых переопределена обработка получения данных выбора (есть обработчик ОбработкаПолученияДанныхВыбора), т.к. прописанные там условия не учитываются механизмом составления списка истории выбора. Поэтому, используя историю выбора в этом случае, пользователь может получить возможность выбрать значение, которое он не мог бы выбрать другими способами.

              \n

              2.2. После отключения истории выбора в свойствах объекта метаданных необходимо, во всех ссылающихся на него полях ввода, установить для следующих свойств указанные ниже значения:

              \n
              \n

              • КнопкаВыпадающегоСпискаНет
              • КнопкаВыбораДа
              • ОтображениеКнопкиВыбораВ поле ввода

              \n

              Это необходимо сделать, чтобы пользователю перед началом выбора в поле ввода не отображалось меню, в котором нужно всегда нажимать «Показать все».

              Например:

              \n

              \n\n\n\n\n\n\n\n
              ПравильноНеправильно

              \n

               

              \n

              Исключения:

              \n

              Можно не изменять значения свойств полей ввода если:

              \n
              \n
              \n

              • для поля ввода установлен режим выбора из списка и заполнен (или в метаданных или программно) список выбора
              • поле ввода ссылается на объект метаданных с установленным свойством Быстрый выбор

              \n

              Для автоматического изменения свойств полей выбора можно воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "413", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Присутствует обработчик \"ОбработкаПолученияДанныхВыбора\", а свойство \"История выбора при вводе\" не равно \"Не использовать\".", +"Description": "

              История выбора при вводе

              #std744

              Область применения: управляемое приложение.

              \n

              1. Для свойства История выбора  большинства объектов метаданных должно быть установлено значение Авто.

              \n

              2.1. Историю выбора в свойствах объекта метаданных рекомендуется отключать, если ее использование не соответствует прикладной логике конфигурации:

              \n
              \n

              • для объектов, сценарий использования которых не предполагает повторный выбор из 5 ранее выбранных вариантов. 

              \n

              Примеры:

              \n
              \n

              Специфика использования большинства документов такова, что повторный их выбор маловероятен, например, выбор объекта расчетов в Поступлении безналичных денежных средств.

              \n

              • для объектов, в модуле менеджера которых переопределена обработка получения данных выбора (есть обработчик ОбработкаПолученияДанныхВыбора), т.к. прописанные там условия не учитываются механизмом составления списка истории выбора. Поэтому, используя историю выбора в этом случае, пользователь может получить возможность выбрать значение, которое он не мог бы выбрать другими способами.

              \n

              2.2. После отключения истории выбора в свойствах объекта метаданных необходимо, во всех ссылающихся на него полях ввода, установить для следующих свойств указанные ниже значения:

              \n
              \n

              • КнопкаВыпадающегоСпискаНет
              • КнопкаВыбораДа
              • ОтображениеКнопкиВыбораВ поле ввода

              \n

              Это необходимо сделать, чтобы пользователю перед началом выбора в поле ввода не отображалось меню, в котором нужно всегда нажимать «Показать все».

              Например:

              \n

              \n\n\n\n\n\n\n\n
              ПравильноНеправильно

              \n

               

              \n

              Исключения:

              \n

              Можно не изменять значения свойств полей ввода если:

              \n
              \n
              \n

              • для поля ввода установлен режим выбора из списка и заполнен (или в метаданных или программно) список выбора
              • поле ввода ссылается на объект метаданных с установленным свойством Быстрый выбор

              \n

              Для автоматического изменения свойств полей выбора можно воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "414", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Неверно установлены свойства поля формы, которое ссылается на объект метаданных с отключенной историей выбора при вводе.", +"Description": "

              История выбора при вводе

              #std744

              Область применения: управляемое приложение.

              \n

              1. Для свойства История выбора  большинства объектов метаданных должно быть установлено значение Авто.

              \n

              2.1. Историю выбора в свойствах объекта метаданных рекомендуется отключать, если ее использование не соответствует прикладной логике конфигурации:

              \n
              \n

              • для объектов, сценарий использования которых не предполагает повторный выбор из 5 ранее выбранных вариантов. 

              \n

              Примеры:

              \n
              \n

              Специфика использования большинства документов такова, что повторный их выбор маловероятен, например, выбор объекта расчетов в Поступлении безналичных денежных средств.

              \n

              • для объектов, в модуле менеджера которых переопределена обработка получения данных выбора (есть обработчик ОбработкаПолученияДанныхВыбора), т.к. прописанные там условия не учитываются механизмом составления списка истории выбора. Поэтому, используя историю выбора в этом случае, пользователь может получить возможность выбрать значение, которое он не мог бы выбрать другими способами.

              \n

              2.2. После отключения истории выбора в свойствах объекта метаданных необходимо, во всех ссылающихся на него полях ввода, установить для следующих свойств указанные ниже значения:

              \n
              \n

              • КнопкаВыпадающегоСпискаНет
              • КнопкаВыбораДа
              • ОтображениеКнопкиВыбораВ поле ввода

              \n

              Это необходимо сделать, чтобы пользователю перед началом выбора в поле ввода не отображалось меню, в котором нужно всегда нажимать «Показать все».

              Например:

              \n

              \n\n\n\n\n\n\n\n
              ПравильноНеправильно

              \n

               

              \n

              Исключения:

              \n

              Можно не изменять значения свойств полей ввода если:

              \n
              \n
              \n

              • для поля ввода установлен режим выбора из списка и заполнен (или в метаданных или программно) список выбора
              • поле ввода ссылается на объект метаданных с установленным свойством Быстрый выбор

              \n

              Для автоматического изменения свойств полей выбора можно воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "415", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: отличаются условия \"Если ... Тогда\" у методов работы с транзакциями.", +"Description": "

              Транзакции: правила использования

              #std783

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

              \n

              1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

              \n\n

              Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

              \n

              1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

              \n

              1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

              \n

              Правильно

              \n

              Процедура ЗаписатьДанныеВИБ()

              \n

                  НачатьТранзакцию();

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                      ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              Неправильно

              \n

              Процедура ЗаписатьДанныеВИБ()
               
                  НачатьТранзакцию();
                  ЗаписатьДокумент();

              \n

              КонецПроцедуры;

              \n

              Процедура ЗаписатьДокумент()

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                  ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

              \n
                \n
              • \n
                метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
                \n
              • \n
                все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
                \n
              • \n
                метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
                \n
              • \n
                необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
                \n
              • \n
                рекомендуется в блоке Исключение делать запись в журнал регистрации;
                \n
              • \n
                при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
              \n

              Пример

              \n

              НачатьТранзакцию();
              Попытка
                  БлокировкаДанных = Новый БлокировкаДанных;
                  ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
                  ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
                  ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
                  БлокировкаДанных.Заблокировать();

              \n

                  ... // чтение или запись данных

                  ДокументОбъект.Записать();

              \n

                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();

              \n

                  ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
                      УровеньЖурналаРегистрации.Ошибка,
                      ,
                      ,
                      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

              \n

                  ВызватьИсключение; // есть внешняя транзакция

              \n

              КонецПопытки;

              \n

              1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

              \n

              1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

              \n

              Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

              \n

              При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

              \n

              Правильно

              \n

              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
              Исключение
                  ... // действия по обработке исключения
              КонецПопытки;

              \n

              Неправильно

              \n

              НачатьТранзакцию();
              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();
              КонецПопытки;

              \n

              1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

              \n

              1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

              \n

              Пример

              \n

              Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

              \n

              1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

              \n

              2. Ограничение на длину транзакции.

              \n

              2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

              \n

              Пример

              \n

              При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

              \n

              2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

              \n

              2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

              \n

              2.2. Следует избегать транзакций, которые выполняются длительное время.

              \n

              Пример

              \n

              Неправильно

              \n

              Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

              \n

              Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

              \n

              Правильно

              \n

              Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

              \n

              См. также Особенности использования транзакций при обмене данными

              \n

              2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

              \n
                \n
              • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
              • блокировки, установленные в транзакции, остаются до конца транзакции; \n
              • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
              • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
              \n

              Все это в целом может снижать эффективность использования ресурсов.

              \n

              2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

              \n

              Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

              \n
                \n
              • \n
                возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
                \n
              • \n
                если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
                \n
              • \n
                так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
              \n

              2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

              \n
                \n
              • \n
                сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
                \n
              • \n
                если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
                \n
              • \n
                проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
                \n
              • \n
                запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
                \n
              • \n
                запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "416", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует описание типа возвращаемого значения в комментарии к экспортной функции.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "417", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Некорректно описан тип некоторых свойств возвращаемого значения в комментарии к экспортной функции.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "419", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В правах роли установлены ограничения (RLS) для объекта метаданных.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n\n\n\n

              Стандартные роли

              #std488

              Область применения: управляемое приложение, обычное приложение.

              \n

              1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

              \n

              1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

              \n

              Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

              \n

              2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
              ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

              \n

              2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
              Эта роль должна:

              \n
                \n
              • позволять самостоятельное использование (может быть назначена пользователям); \n
              • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
              • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
              • включать в себя перечисленные права: \n
                  \n
                • Администрирование данных \n
                • Активные пользователи \n
                • Журнал регистрации \n
                • Монопольный режим \n
                • Тонкий клиент \n
                • Веб-клиент \n
                • Сохранение данных пользователя \n
                • Вывод
              \n

              В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

              \n

              При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

              \n

              2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
              Эта роль должна:

              \n
                \n
              • \n
                \n
                назначаться пользователям только совместно с ролью ПолныеПрава;
                \n
              • \n
                \n
                предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
                \n
              • \n
                содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
                \n
              • \n
                включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
              \n

              2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
              Эта роль должна:

              \n
                \n
              • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
              \n

              При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

              \n

              При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

              \n

              2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

              \n

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

              \n

              3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

              \n

              Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

              \n

              3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

              \n

              3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

              \n

              3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

              \n

              3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

              \n

              3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

              \n

              3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

              \n

              3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

              \n

              3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

              \n

              3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

              \n

              3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

              \n

              3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

              \n

              3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

              \n

              Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

              \n
                \n
              • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
              • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
              • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
              \n

              то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

              \n
              \n

              См. также: Работа с пользовательскими настройками

              \n

              4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

              \n

              4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
              Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

              \n

              4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

              \n

              При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

              \n

              5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

              \n
                \n
              • Право интерактивного удаления \n
              • Интерактивное удаление предопределенных данных \n
              • Интерактивная пометка удаления предопределенных данных \n
              • Интерактивное снятие пометки удаления предопределенных данных \n
              • Интерактивное удаление помеченных предопределенных данных
              \n

              Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "420", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В праве \"Удаление\" роли установлены ограничения (RLS) для объекта метаданных.", +"Description": "

              Стандартные роли

              #std488

              Область применения: управляемое приложение, обычное приложение.

              \n

              1.1. Если в конфигурации есть разграничение прав доступа пользователей к данным информационной базы, то настройку доступа следует выполнять с помощью ролей. Роли должны создаваться разработчиком конфигурации исходя из задачи ограничения доступа пользователей к данным.

              \n

              1.2. В простейшем случае, роли в конфигурации могут непосредственно соответствовать должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.).

              \n

              Для возможности более тонкой настройки прав доступа администратором, роли могут соответствовать более «мелким» отдельным функциям, совокупность которых образует набор прав для конкретной категории пользователей. В этом случае пользователям назначается комбинация ролей (например, ЧтениеПроизводственныхДокументов, ДобавлениеИзменениеСкладскихДокументов, ЧтениеНСИ и т.п.). Для упрощения администрирования рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для директора, бухгалтера, кладовщика и т.п.) При использовании в конфигурации Библиотеки стандартных подсистем для этого можно воспользоваться средствами подсистемы «Управление доступом».

              \n

              2. В конфигурации должны быть определены три обязательные роли, которые предназначены для «прикладного» и системного администрирования информационной базы, а также для интерактивного открытия внешних отчетов и обработок:
              ПолныеПрава (синоним «Полные права»), АдминистраторСистемы (синоним «Администратор системы») и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (синоним «Интерактивное открытие внешних отчетов и обработок»).

              \n

              2.1. ПолныеПрава (англ. FullAccess) - обязательная роль, которая предоставляет неограниченный доступ ко всем «прикладным» данным информационной базы, но не дает прав доступа для администрирования информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
              Эта роль должна:

              \n
                \n
              • позволять самостоятельное использование (может быть назначена пользователям); \n
              • предоставлять неограниченный доступ ко всем данным области (к разделенным данным), кроме права интерактивного удаления (см. также п.5); \n
              • позволять выполнять все административные действия с областью данных (администрирование пользователей, настройка программы, удаление помеченных объектов и т.п.); \n
              • включать в себя перечисленные права: \n
                  \n
                • Администрирование данных \n
                • Активные пользователи \n
                • Журнал регистрации \n
                • Монопольный режим \n
                • Тонкий клиент \n
                • Веб-клиент \n
                • Сохранение данных пользователя \n
                • Вывод
              \n

              В случае если конфигурация рассчитана на работу в модели сервиса, то роль ПолныеПрава назначается администраторам абонентов (администраторам областей данных).

              \n

              При работе конфигурации в локальном режиме роль ПолныеПрава назначается пользователям совместно с ролью АдминистраторСистемы, так как в этом режиме функции системного и «прикладного» администрирования информационной базы, как правило, совмещены.

              \n

              2.2. АдминистраторСистемы (англ. SystemAdministrator) – обязательная роль, предоставляющая дополнительные права на администрирование информационной базы в целом (обновление конфигурации, работа в конфигураторе и т.п.).
              Эта роль должна:

              \n
                \n
              • \n
                \n
                назначаться пользователям только совместно с ролью ПолныеПрава;
                \n
              • \n
                \n
                предоставлять неограниченный доступ ко всем неразделенным данным информационной базы;
                \n
              • \n
                содержать все права доступа к объектам (кроме права интерактивного удаления - см. ниже п.5);
                \n
              • \n
                включать в себя все права к корню конфигурации (в частности, права Администрирование и Администрирование данных), кроме прав Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
              \n

              2.3. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) обязательная роль, предоставляющая дополнительные права на открытие внешних отчетов и обработок через меню «Файл – Открыть».
              Эта роль должна:

              \n
                \n
              • включать в себя права к корню конфигурации Интерактивное открытие внешних отчетов и Интерактивное открытие внешних обработок.
              \n

              При работе конфигурации в локальном режиме роль ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначается администраторам, но в целях повышения безопасности информационной базы администратор может запретить использование данной роли.

              \n

              При работе в модели сервиса роли АдминистраторСистемы, ПолныеПрава и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок назначаются администраторам сервиса.

              \n

              2.4. Роли ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок должны устанавливаться как основные роли конфигурации (свойство ОсновныеРоли).

              \n

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5. При необходимости дать возможность удаления объектов «неполноправным» пользователям, рекомендуется добавить отдельную роль УдалениеПомеченныхОбъектов (англ. DeleteMarkedObjects). Такая роль не предназначена для самостоятельного использования, ее следует назначать пользователям совместно с остальными ролями конфигурации.

              \n

              3. Роли для настройки общих прав на информационную базу. В случае если в конфигурации для пользователей необходимо настраивать общие права работы с информационной базой (такие как «Тонкий клиент», «Толстый клиент», «Интерактивное открытие внешних обработок» и т.д.), то в конфигурации должны быть определены отдельные роли для предоставления этих прав. Такие роли не предназначены для самостоятельного использования, их следует назначать пользователям совместно с остальными ролями конфигурации.

              \n

              Конфигурация должна быть одинаково рассчитана на работу как при наличии этих ролей, так и в условиях отсутствия любой из этих ролей у пользователя.

              \n

              3.1. Администрирование (англ. Administration) - предоставляет права «Администрирование», «Администрирование данных», «Администрирование расширений конфигурации» и «Активные пользователи».

              \n

              3.2. ВыводНаПринтерФайлБуферОбмена (англ. OutputToPrinterFileClipboard) - предоставляет право «Вывод».

              \n

              3.3. ЗапускAutomation (англ. StartAutomation) - предоставляет право «Automation».

              \n

              3.4. ЗапускВебКлиента (англ. StartWebClient)- предоставляет право «Веб-клиент».

              \n

              3.5. ЗапускВнешнегоСоединения (англ. StartExternalConnection) - предоставляет право «Внешнее соединение»

              \n

              3.6. ЗапускТолстогоКлиента (англ. StartThickClient)- предоставляет право «Толстый клиент».

              \n

              3.7. ЗапускТонкогоКлиента (англ. StartThinClient) - предоставляет право «Тонкий клиент».

              \n

              3.8. ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок (англ. InteractiveOpenExternalReportsAndDataProcessors) - предоставляет права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов».

              \n

              3.9. ОбновлениеКонфигурацииБазыДанных (англ. UpdateDatabaseConfiguration) - предоставляет право «Обновление конфигурации базы данных».

              \n

              3.10. ПросмотрЖурналаРегистрации (англ. ViewEventLog) - предоставляет право «Журнал регистрации».

              \n

              3.11. РежимВсеФункции (англ. AllFunctionsMode) - предоставляет право «Режим \"Все функции\"». Этот режим предназначен только для разработчиков/внедренцев и для разбора нештатных ситуаций, поэтому конфигурация должна обеспечивать работу пользователей без использования этого режима. Например, все стандартные обработки (удаление помеченных, управление итогами и агрегатами и т.п.) должны быть доступны соответствующим пользователям в разделах интерфейса программы.

              \n

              3.12. СохранениеДанныхПользователя (англ. SaveUserData) - предоставляет право «Сохранение данных пользователя». Рекомендуется предоставлять эту роль всем категориям пользователей, за редким исключением, когда требуется явно запретить настройку пользовательского интерфейса и любые другие персональные настройки таким образом, чтобы работа пользователя не оставляла никаких «следов» в информационной базе. Как правило, такой режим работы требуется для внешних или временных пользователей (респонденты, аудиторы и пр.) или для пользователей, работающих по тем или иным причинам под одной учетной записью.

              \n

              Конфигурация должна быть рассчитана на работу пользователей без роли (права) СохранениеДанныхПользователя. В случае если конфигурация обращается из кода

              \n
                \n
              • к пользовательским настройкам (сохранение и загрузка из различных хранилищ настроек: ХранилищеОбщихНастроек, ХранилищеВариантовОтчетов, ХранилищеНастроекДанныхФорм, ХранилищеПользовательскихНастроекОтчетов, ХранилищеСистемныхНастроек) \n
              • к истории работы пользователя (ИсторияРаботыПользователя) и избранному (ИзбранноеРаботыПользователя) \n
              • к пользовательским настройкам отчетов (метод УстановитьТекущиеПользовательскиеНастройки расширения управляемой формы для отчета)
              \n

              то при отсутствии у пользователя права СохранениеДанныхПользователя, этот код должен быть пропущен таким образом, чтобы это не оказывало влияния на основные сценарии работы пользователя. Кроме того, если в конфигурации предусмотрены пользовательские интерфейсы или отдельные элементы форм для работы с пользовательскими настройками (история вводимых значений, флажки «Запомнить мой выбор» и пр.), то они не должны быть доступны пользователям без права СохранениеДанныхПользователя.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем можно также воспользоваться функциями ХранилищеОбщихНастроекЗагрузить и ХранилищеОбщихНастроекСохранить общего модуля ОбщегоНазначения.

              \n
              \n

              См. также: Работа с пользовательскими настройками

              \n

              4.1. В тех случаях когда определенным пользователям требуется временный или постоянный доступ на просмотр всех данных информационной базы без ограничений, рекомендуется поставлять в составе конфигурации отдельные роли. Например, это может быть временный доступ для аудитора, постоянный – для собственника или директора организации.

              \n

              4.2. В простейшем случае, когда роли в конфигурации соответствуют должностным обязанностям пользователей (Директор, Бухгалтер, Кладовщик и т.п.), должна быть добавлена отдельная роль ТолькоПросмотр (англ. ViewOnly).
              Роль ТолькоПросмотр должна включать права Чтение, Использование, Просмотр, Ввод по строке (если применимо) для большинства объектов метаданных (за исключением тех данных, которые никогда не выводятся пользователю, а используются в конфигурации только в технологических целях, и поэтому доступ к ним осуществляется всегда в привилегированном режиме).

              \n

              4.3. В конфигурациях, в которых роли соответствуют более «мелким» отдельным функциям (совокупность которых образует набор прав для конкретной категории пользователей), рекомендуется назначать пользователям комбинацию ролей, которые предоставляют доступ только на чтение (например, ЧтениеПроизводственныхДокументов, ЧтениеСкладскихДокументов, ЧтениеКассовыхДокументов и т.п.). Рекомендуется поставлять в составе конфигурации типовые комбинации таких ролей (например, готовый профиль для аудитора, собственника, директора и т.п.)

              \n

              При этом для неограниченного доступа на просмотр всех данных информационной базы для таких пользователей нужно отключать (не задавать) условия ограничения доступа на уровне записей (RLS).

              \n

              5. Ни в одной роли, включая ПолныеПрава и АдминистраторСистемы, не должно быть установлено (кроме отдельных обоснованных случаев) следующих прав:

              \n
                \n
              • Право интерактивного удаления \n
              • Интерактивное удаление предопределенных данных \n
              • Интерактивная пометка удаления предопределенных данных \n
              • Интерактивное снятие пометки удаления предопределенных данных \n
              • Интерактивное удаление помеченных предопределенных данных
              \n

              Право удаления рекомендуется оставить только в ролях ПолныеПрава и АдминистраторСистемы.

              \n

              См. также

              \n\n\n\n

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "421", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Права на константу установлены в обеих ролях: \"Полные права\" и \"Администратор системы\".", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "422", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Права на константу не установлены ни в одной из ролей: \"Полные права\" и \"Администратор системы\".", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "423", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Для роли \"Изменение<ИмяКонстанты>\" установлены права на другой объект метаданных.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "424", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Для роли \"Чтение<ИмяКонстанты>\" установлены права на другой объект метаданных.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "425", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Отсутствует область \"ОписаниеПеременных\" в тексте модуля.", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "426", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Переменная объявлена в области, содержащей процедуру или функцию.", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "427", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует область \"Инициализация\" в тексте модуля.", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "428", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Операторы раздела инициализации расположены в области, содержащей процедуры или функции.", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "429", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Переменная объявлена вне области \"ОписаниеПеременных\".", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "430", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Операторы раздела инициализации расположены вне области \"Инициализация\".", +"Description": "

              Структура модуля

              #std455

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. В программном модуле (общие модули, модули объектов, модули менеджеров объектов, модули форм, команд и т.п.) в общем случае могут присутствовать следующие разделы в приведенной ниже последовательности:

              \n
                \n
              • заголовок модуля \n
              • раздел описания переменных \n
              • экспортные процедуры и функции модуля, составляющие его программный интерфейс \n
              • обработчики событий объекта (формы) \n
              • служебные процедуры и функции модуля \n
              • раздел инициализации
              \n

              Некоторые разделы могут присутствовать только в модулях определенного вида. Например, обработчики событий элементов форм могут присутствовать только в модулях форм, а раздел описания переменных и раздел инициализации не могут быть определены в неглобальных общих модулях, модулях менеджеров объектов, наборов записей, значений констант и модуле сеанса.

              \n

              Требование о разделении кода модуля на разделы призвано повысить читаемость кода и упростить внесение изменений в код разными авторами (разработчиками) как при коллективной разработке, так и при доработке прикладных решений на конкретных внедрениях.

              \n

              1.2. Объемные разделы модулей рекомендуется разбивать на подразделы по функциональному признаку.

              \n

              1.3. Разделы и подразделы оформляются в виде областей. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              1.4. Шаблон (заготовка для копирования) разделов для общих модулей:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования другими объектами конфигурации или другими программами (например, через внешнее соединение). \n
              • Раздел «Служебный программный интерфейс»  предназначен для модулей, которые являются частью некоторой функциональной подсистемы. В нем должны быть размещены экспортные процедуры и функции, которые допустимо вызывать только из других функциональных подсистем этой же библиотеки. \n
              • Раздел «Служебные процедуры и функции» содержит процедуры и функции, составляющие внутреннюю реализацию общего модуля. В тех случаях, когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

                Для объемных общих модулей рекомендуется разбивать этот раздел на подразделы, по функциональному признаку. Например: 
              \n

              русск.

              #Область ОбновлениеИнформационнойБазы\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region InfobaseUpdate\n// Enter code here.\n#EndRegion\n
              \n

              1.5. Шаблон оформления разделов для модулей объектов, менеджеров, наборов записей, обработок, отчетов и т.п.:

              \n

              русск.

              #Область ПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныйПрограммныйИнтерфейс\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region Public\n// Enter code here.\n#EndRegion\n\n#Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Internal\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Программный интерфейс» содержит экспортные процедуры и функции, предназначенные для использования в других модулях конфигурации или другими программами (например, через внешнее соединение). Не следует в этот раздел помещать экспортные функции и процедуры, которые предназначены для вызова исключительно из модулей самого объекта, его форм и команд. Например, процедуры заполнения табличной части документа, которые вызываются из обработки заполнения в модуле объекта и из формы документа в обработчике команды формы не являются программным интерфейсом модуля объекта, т.к. вызываются только в самом модуле и из форм этого же объекта. Их следует размещать в разделе «Служебные процедуры и функции». \n
              • Раздел «Обработчики событий» содержит обработчики событий модуля объекта (ПриЗаписи, ПриПроведении и др.) \n
              • Раздел «Служебный программный интерфейс» имеет такое же предназначение, как и в общих модулях. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, как и в общих модулях.
              \n

              1.6. Шаблон оформления разделов для модулей форм:

              \n

              русск.

              #Область ОбработчикиСобытийФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовШапкиФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиСобытийЭлементовТаблицыФормы<ИмяТаблицыФормы>\n// Код процедур и функций\n#КонецОбласти\n\n#Область ОбработчикиКомандФормы\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region FormEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormHeaderItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormTableItemsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region FormCommandsEventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n
                \n
              • Раздел «Обработчики событий формы» содержит процедуры-обработчики событий формы: ПриСозданииНаСервере, ПриОткрытии и т.п. \n
              • Раздел «Обработчики событий элементов шапки формы» содержит процедуры-обработчики элементов, расположенных в основной части формы (все, что не связано с таблицами на форме). \n
              • В разделах «Обработчики событий элементов таблицы формы <имя таблицы формы>» размещаются процедуры-обработчики таблиц формы и элементов таблиц. Для процедур-обработчиков каждой таблицы должен быть создан свой раздел. \n
              • Раздел «Обработчики команд формы» содержит процедуры-обработчики команд формы (имена которых задаются в свойстве Действие команд формы). \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n
              \n

              См. также: Правила создания модулей форм

              \n

              1.7. Шаблон оформления разделов для модулей команд:

              \n

              русск.

              #Область ОбработчикиСобытий\n// Код процедур и функций\n#КонецОбласти\n\n#Область СлужебныеПроцедурыИФункции\n// Код процедур и функций\n#КонецОбласти\n
              \n

              англ.

              #Region EventHandlers\n// Enter code here.\n#EndRegion\n\n#Region Private\n// Enter code here.\n#EndRegion\n
              \n


              \n
                \n
              • Раздел «Обработчики событий» содержит процедуру-обработчик команды ОбработкаКоманды. \n
              • Раздел «Служебные процедуры и функции» имеет такое же предназначение, что и в общих модулях.
              \n

              1.8. В модуле не должно быть пустых областей.

              \n

              2. Общие требования к разделам программных модулей.

              \n

              2.1. Заголовок модуля представляет собой комментарий в самом начале модуля. В заголовке модуля приводится его краткое описание и условия применения.
              Например:

              ////////////////////////////////////////////////////////////////////////////////\n// Клиентские процедуры и функции общего назначения:\n// - для работы со списками в формах;\n// - для работы с журналом регистрации;\n// - для обработки действий пользователя в процессе редактирования\n//   многострочного текста, например комментария в документах;\n// - прочее.\n//  \n////////////////////////////////////////////////////////////////////////////////\n
              \n

              Для модулей форм в заголовке рекомендуется размещать описание параметров формы.

              \n

              2.2. Раздел описания переменных. Имена переменных назначаются согласно общим правилам образования имен переменных, а их использование описывается в статье Использование глобальных переменных в программных модулях.

              \n

              Все переменные модуля должны быть снабжены комментарием, достаточным для понимания их назначения. Комментарий рекомендуется размещать в той же строке, где объявляется переменная.
              Пример:

              \n

              русск.

              #Область ОписаниеПеременных\n\nПерем ВалютаУчета;\nПерем АдресПоддержки;\n...\n\n#КонецОбласти\n
              \n

              англ.

              #Region Variables\n\nVar PresentationCurrency;\nVar SupportEmail;\n...\n\n#EndRegion\n
              \n

              2.3. Программный интерфейс. Экспортные процедуры и функции, составляющие его программный интерфейс, размещаются сразу же после описания переменных. Такие процедуры и функции предназначены для использования другими объектами конфигурации или другими программами (например, через внешнее соединение), поэтому должны быть расположены в модуле на \"видном месте\".

              \n
              \n

              См. также: Описание процедур и функций

              \n

              2.4.1. Обработчики событий формы, команд и элементов формы. Перед служебными процедурами и функциями в модуле формы располагаются обработчики событий формы, а также обработчики событий команд и элементов формы.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.4.2. Рекомендуется обработчики одного элемента формы располагать вместе, придерживаясь, при этом, порядка их следования в панели свойств редактора формы в конфигураторе.

              \n

              2.4.3. У каждого события должна быть назначена своя процедура-обработчик. Если одинаковые действия должны выполняться при возникновении событий в разных элементах формы следует:

              \n
                \n
              • \n
                создать отдельную процедуру (функцию), выполняющую необходимые действия
                \n
              • \n
                для каждого элемента формы создать отдельный обработчик с именем, назначаемым по умолчанию
                \n
              • \n
                из каждого обработчика вызвать требуемую процедуру (функцию).
              \n

              Например, неправильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n ПоИсполнителюПриИзменении(Неопределено);\nКонецПроцедуры\n
              \n

              правильно:

              &НаКлиенте\nПроцедура ПоИсполнителюПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаКлиенте\nПроцедура ПоАвторуПриИзменении(Элемент)\n УстановитьОтбор();\nКонецПроцедуры\n\n&НаСервере\nПроцедура УстановитьОтбор()\n ПараметрыОтбора = Новый Соответствие();\n ПараметрыОтбора.Вставить(\"ПоАвтору\", ПоАвтору);\n ПараметрыОтбора.Вставить(\"ПоИсполнителю\", ПоИсполнителю);\n УстановитьОтборСписка(Список, ПараметрыОтбора);\nКонецПроцедуры \n
              \n

              Это требование обусловлено тем, что логически процедуры-обработчики событий не предназначены для использования в коде модуля, а вызываются непосредственно платформой. Смешение же этих двух сценариев в одной процедуре неоправданно усложняет ее логику и снижает ее устойчивость (вместо одного предусмотренного сценария вызова - по событию из платформы - код процедуры должен рассчитывать и на другие \"прямые\" вызовы из кода).

              \n

              2.5. Обработчики событий модулей объекта и менеджера объекта размещаются после раздела с программным интерфейсом, но до служебных процедур и функций модуля.   \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2.5.1. Рекомендуется располагать обработчики, придерживаясь порядка их следования в описании встроенного языка.

              \n

              2.6. Служебные процедуры и функции модуля, которые не являются обработчиками событий, а составляют внутреннюю реализацию модуля, размещаются в модуле следом за обработчиками событий.

              \n

              В тех случаях когда общий модуль является частью некоторой функциональной подсистемы, включающей в себя несколько объектов метаданных, в этом разделе также могут быть размещены служебные экспортные процедуры и функции, предназначенные только для вызова из других объектов данной подсистемы.

              \n

              Процедуры и функции, связанные между собой по характеру или по логике работы рекомендуется располагать вместе. В модулях форм не рекомендуется явно группировать процедуры и функции модуля на серверные, клиентские и функции без контекста, так как такое «технологическое» упорядочивание затрудняет понимание логики модуля, отвлекая внимание разработчика на детали ее реализации.

              \n

              2.7. Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
              Например:

              \n

              русск.

              #Область Инициализация\n\nАдресПоддержки = \"v8@1c.ru\"; \nВыполнитьИнициализацию();\n...\n\n#КонецОбласти
              \n

              англ.

              #Region Initialize\n\nSupportEmail = \"v8@1c.ru\";\nCtor();\n...\n\n#EndRegion\n
              \n


              \n

              Для оформления разделов кода в виде областей рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "433", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Неэкспортная переменная не используется в модуле.", +"Description": "

              Тексты модулей

              #std456

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Тексты модулей должны быть написаны на русском языке. 

              \n

              Исключение составляют веб-сервисы, имена методов и параметров которых рекомендуется задавать на английском языке (например, метод TestConnection веб-сервиса EnterpriseDataExchange), а также различные идентификаторы сторонних информационных систем, например, названия полей «внешних» структур данных, которые программно обрабатываются в коде.

              \n

              1.1. В текстах модулях не допускается использовать букву \"ё\".

              \n

              Исключения составляют интерфейсные тексты, выводимые пользователю в сообщениях, формах и справке, где употребление буквы «ё» в ряде случаев допустимо. Подробнее см. Тексты.

              \n

              1.2. Кроме того, в текстах модулей не допускается использовать неразрывные пробелы и знак минус \"-\" в других кодировках (короткое, длинное тире и т.п.).

              \n

              Такие символы часто оказываются в тексте модулей при копировании из офисных документов и приводят к ряду сложностей при разработке. Например, не работает поиск фрагментов текста, включающих «неправильные» минусы и пробелы; некорректно выводятся подсказки типов параметров процедур и функций в конфигураторе и расширенная проверка в 1С:EDT; указание «неправильного» минуса в выражениях приведет к синтаксической ошибке.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Программные модули не должны иметь неиспользуемых процедур и функций.

              \n

              3. Программные модули не должны иметь закомментированных фрагментов кода, а также фрагментов, которые каким-либо образом связаны с процессом разработки (отладочный код, служебные отметки, например, TODO, MRG и т.п.) и с конкретными разработчиками этого кода. Например, недопустимо оставлять подобные фрагменты в коде после завершения отладки или рефакторинга:

              Процедура ПередУдалением(Отказ)\n//    Если Истина Тогда\n//        Сообщение(\"Для отладки\");\n//    КонецЕсли;\nКонецПроцедуры\n
              \n

              также неправильно:

              Процедура ПередУдалением(Отказ)\n    Если Истина Тогда\n        // Иванов: доделать \n    КонецЕсли;\nКонецПроцедуры\n
              \n

              Правильно: после завершения отладки или рефакторинга удалить обработчик ПередУдалением из кода.

              \n

              4. Тексты модулей оформляются по принципу \"один оператор в одной строке\". Наличие нескольких операторов допускается только для \"однотипных\" операторов присваивания, например:

              НачальныйИндекс = 0; Индекс = 0; Результат = 0;\n
              \n

              5. Текст модуля должен быть оформлен синтаксическим отступом. Для синтаксического отступа используется табуляция (а не пробелы, чтобы при смене числа знаков в табуляции выравнивание текста сохранялось).

              \n

              Размер табуляции - стандартный (4 символа).

              5.1. С крайней левой позиции должны начинаться только:

              \n
                \n
              • операторы Процедура, КонецПроцедуры, Функция, КонецФункции;  \n
              • операторы предварительного объявления процедур и функций;  \n
              • заголовки (описания) процедур и функций;  \n
              • объявление переменных модуля;  \n
              • операторы \"раздела основной программы\" (с учетом синтаксического отступа); \n
              • директивы компилятора &НаКлиенте, &НаСервере и т.д. \n
              • инструкции препроцессора (в т.ч. #Область и #КонецОбласти)
              \n

              5.2. Процедуры НачатьТранзакцию и ЗафиксироватьТранзакцию не являются операторными скобками, поэтому текст внутри этих процедур не сдвигается.

              6. При длине строки более 120 символов следует использовать переносы. Строки длиннее 120 символов делать не рекомендуется, за исключением тех случаев, когда перенос невозможен (например, в коде определена длинная строковая константа, которая выводится без переносов в окно сообщений с помощью объекта СообщениеПользователю).

              \n
              \n

              См. также: Перенос выражений.

              \n

              7.1. Тексты модулей могут содержать комментарии. Комментарии должны быть достаточно понятными, чтобы пояснять работу модуля или комментируемого оператора. Тексты комментариев должны составляться по правилам русского языка, в деловом стиле, быть эмоционально сдержанными и не содержать слов, не относящихся к функциональности программы. 

              \n

              7.2. Небольшие комментарии пишутся в конце строки, которую комментируют, например:

              НайденныеОшибки.Колонки.Добавить(\"Номер\"); // для совместимости\n
              \n

              7.3. Большие комментарии или комментарии к фрагменту кода пишутся перед комментируемым кодом в отдельной строке. Текст выравнивается по левой границе комментируемого фрагмента. Между символами комментария \"//\" и текстом комментария должен быть пробел.

              // Инициализируем переменные для выполнения расчетов,\n// которые выполняются далее по тексту модуля.\nТекущаяДата = ОбщегоНазначения.ПолучитьРабочуюДату(); \nТекущийГод = Год(ТекущаяДата); \nТекущийМесяц = Месяц(ТекущаяДата); \nТекущаяНеделя = НеделяГода(ТекущаяДата); \nТекущийДень = День(ТекущаяДата);\n
              \n

              8. Тексты больших процедур и функций можно разбивать на отдельные сворачиваемые области. При этом имена областей должны удовлетворять требованиям стандарта Правила образования имен переменных

              \n

              Для автоматического форматирования кода можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "435", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Возврат константы типа Строка в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "436", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Возврат константы типа Число в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "437", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Возврат константы типа Дата в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "438", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Возврат константы типа Булево в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "439", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Возврат предопределенного элемента в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "441", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует удаление временного файла после использования.", +"Description": "

              Доступ к файловой системе из кода конфигурации

              #std542

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При обращении из кода конфигурации к файлам и каталогам файловой системы следует иметь в виду, что доступ к ним ограничен правами пользователя операционной системы, от имени которого запущено приложение.

              \n

              1.1. Если доступ к файловой системе осуществляется из кода, выполняемого на клиенте, то он выполняется под правами пользователя, от имени которого запущено приложение (тонкий, толстый или веб-клиент). Как правило, это текущий пользователь операционной системы.

              \n

              1.2. Если доступ к файловой системе осуществляется из кода, выполняемого на сервере, то:

              \n
                \n
              • при использовании клиент-серверной информационной базы, доступ ограничен правами пользователя, от имени которого запущен сервер 1С:Предприятия (*); \n
              • при использовании файловой базы, опубликованной на веб-сервере, доступ ограничен правами пользователя, от имени которого запущен веб-сервер.
              \n

              * Рабочие процессы могут быть также запущены от имени другого пользователя, отличного от того, под которым запускается агент сервера. Подробнее см. руководство администратора клиент-серверного варианта, описание служебного файла swpuser.ini

              \n\n\n\n
              \n

                   Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              2. Запрещается выполнять запись каких-либо файлов в каталог исполняемых файлов 1С:Предприятия, получаемого с помощью метода КаталогПрограммы. Использование метода КаталогПрограммы допустимо только для чтения или запуска файлов. Например, при работе в ОС Windows, для запуска копии тонкого клиента 1С:Предприятия текущей версии, допустимо использовать:

              \n

              ЗапуститьПриложение(КаталогПрограммы() + \"1cv8s.exe\");

              \n

              3. Даже если не планируется локализация конфигурации на другие языки, следует обеспечивать переносимость файлов, сформированных из кода конфигурации, между различными операционными системами с различными кодировками. Для этого необходимо:

              \n

              3.1. В именах файлов, автоматически формируемых из кода конфигурации, указывать только английские буквы, а также цифры, а в качестве кодировки текстовых файлов использовать только UTF-8 (именно этот формат предпочтителен, т.к. только с ним корректно работает операционная система macOS).

              \n

              Это ограничение распространяется на файлы сообщений обмена, выгрузки данных, электронных документов и пр., которые автоматические формируются системой, в том числе на файлы, упакованные в архивы (например, zip). Исключение составляют случаи, когда на формат файлов невозможно повлиять, например, это формат сторонней системы.

              \n

              3.2. В тех случаях, когда имя файла не генерируется системой, а его явно вводит пользователь, разрешить ввод русскоязычных имен, но при этом дать возможность транслитерировать его в англоязычное имя. По умолчанию, если это технически возможно и не снижает удобство работы, рекомендуется предлагать англоязычное имя файла, а для текстовых файлов – сохранение в кодировке UTF-8. 

              \n

              Также эти рекомендации по выбору имени и кодировки файла следует разместить в справке к тем местам программы, где пользователь имеет возможность сохранять файлы и выбирать кодировку.

              \n

              В конфигурациях на базе Библиотеки стандартных подсистем для транслитерации имен файлов рекомендуется использовать функцию СтроковыеФункцииКлиентСервер.СтрокаЛатиницей.

              \n

              \n

              Работа с временными файлами и каталогами

              \n

              При необходимости использования временных файлов и каталогов необходимо соблюдать следующие требования:

              \n

              1. Для получения имени временного файла следует использовать метод ПолучитьИмяВременногоФайла (исключение составляет веб-клиент, см. ниже п. 3). В противном случае возможна некорректная работа конфигурации в многопользовательском режиме, с включенными профилями безопасностями, возникновение проблем с правами доступа к файлам операционной системы, а также неконтролируемое увеличение количества ненужных временных файлов, которые не будут своевременно удалены.

              \n

              Например, неправильно:

              \n

              ИмяПромежуточногоФайла = \"C:\\Временные файлы 1С\\TempFile.xml\";
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              У текущего пользователя может не быть прав на запись в указанный каталог. Кроме того, при одновременном выполнении этого кода из двух разных сеансов возникнет ошибка.

              \n

              Правильно:

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              При использовании этой функции будет получено уникальное имя, гарантирован доступ к файлу.

              \n

              Кроме того, при использовании метода ПолучитьИмяВременногоФайла платформа 1С:Предприятие сохраняет контроль над такими файлами и автоматически удаляет их при перезапуске рабочего процесса (если файл был создан на стороне сервера) или клиентского приложения (если файл был создан на стороне клиента).

              \n

              Если же имя временного файла было сформировано каким-то другим способом, и прикладной код не удалил (либо по какой-то причине не смог удалить) ранее созданный временный файл, то платформа такой файл не контролирует, и он остается в файловой системе на неопределенное время. Накапливание «потерянных» временных файлов может представлять серьезную проблему, особенно для информационных баз с большим количеством активно работающих пользователей (например, при работе в режиме сервиса).

              \n

              Таким образом, неправильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = Строка(Новый УникальныйИдентификатор) + \".xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              Если по каким-то причинам прикладной код не удалит созданный файл (например, между блоками создания и удаления временного файла возникнет штатное или нештатное исключение), этот файл так и останется в каталоге временных файлов.

              \n

              Правильно:

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              При использовании метода ПолучитьИмяВременногоФайла будет получено уникальное имя, гарантирован доступ к файлу, а также временный файл будет автоматически удален платформой 1С:Предприятие после завершения рабочего процесса сервера или клиентского приложения.

              \n

              2. Для создания временного каталога рекомендуется также использовать имя, полученное при помощи метода ПолучитьИмяВременногоФайла (исключение составляет веб-клиент, см. ниже п. 3). Это гарантирует уникальность имени создаваемого каталога при работе в многопользовательском режиме и гарантирует, что после перезапуска рабочего процесса или клиентского приложения временный каталог будет автоматически удален платформой 1С:Предприятие. После этого, внутри созданного каталога можно создавать другие каталоги и файлы без ограничений.

              \n

              3.1. При выполнении кода веб-клиентом метод ПолучитьИмяВременногоФайла недоступен. Поэтому для формирования имен временных файлов и каталогов необходимо использовать функцию КаталогВременныхФайлов и объект УникальныйИдентификатор.

              \n

              Неправильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = \"TempDataFile.xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              Правильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = Строка(Новый УникальныйИдентификатор) + \".xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              3.2. Если в конфигурацию встроена Библиотека стандартных подсистем, для создания временных каталогов на стороне клиента необходимо использовать процедуру ФайловаяСистемаКлиент.СоздатьВременныйКаталог.

              \n

              4. После окончания работы с временным файлом или каталогом, его необходимо удалить самостоятельно. Нельзя рассчитывать на автоматическое удаление файлов и каталогов при следующем запуске платформы, это может привести к исчерпанию свободного места в каталоге временных файлов.

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              // Работа с файлом
              ...

              \n

              // Удаляем временный файл
              Попытка
                 УдалитьФайлы(ИмяПромежуточногоФайла);
              Исключение
                 ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие'\"), УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
              КонецПопытки;

              \n
              \n

              См. также: Использование Журнала регистрации.

              \n

              5. При использовании временных файлов и каталогов на сервере, необходимо полностью завершать работу с ними в рамках одного серверного вызова. При работе конфигурации с использованием кластера серверов, при следующем вызове эти файлы могут стать недоступны, так как код начнет исполняться на другом компьютере. При необходимости сохранить данные между серверными вызовами в пределах одного сеанса следует использовать временное хранилище платформы (методы ПоместитьВоВременноеХранилище, ПолучитьИзВременногоХранилища).

              \n

              5.1. В редких случаях может возникнуть необходимость передачи данных во временных файлах между сеансами, например, при подготовке данных для фонового задания, при организации длительного процесса, обслуживающего несколько последовательных вызовов web-сервиса. Необходимо самостоятельно обеспечивать гарантировано общее место хранения, права для доступа к файлам из разных мест их обработки, удаление файлов по истечению сроков их обработки или аварийного завершения процесса обработки. Рекомендуется использовать следующий подход:

              \n
                \n
              • Для обеспечения доступа со всех возможных мест обработки заводится константа для хранения общего пути к файлам, доступного для доступа со всех серверов кластера; \n
              • При создании временных файлов их имена заносятся во вспомогательный регистр сведений с сохранением времени создания файла; \n
              • При штатном прохождении процесса, последняя операция, которой были нужны файлы, перед своим завершением удаляет как сам файл, так и записи о них во вспомогательном регистре; \n
              • Вспомогательное регламентное задание периодически проверяет наличие записей во вспомогательном регистре, время существования которых заведомо превышает время штатного завершения процесса. При обнаружении таких записей, задание удаляет временные файлы и записи о них.
              \n

              \n

              Передача файлов между клиентом и сервером

              \n

              1. При одновременной работе с файлом на клиенте и на сервере необходимо использовать передачу файла через временное хранилище (методы ПоместитьФайлы, ПолучитьФайл, ПолучитьФайлы, НачатьПомещениеФайла, ПоместитьВоВременноеХранилище, ПолучитьИзВременногоХранилища). В общем случае клиент и серверы кластера - это разные компьютеры с разной файловой системой, причем доступ к файлам может происходить под разными пользователями ОС с различными правами.

              \n

              Неправильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...
                 ИмяФайла = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 Результат = ПроизвестиОбработкуНаСервере(ИмяФайла);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаСервере
              Функция ПроизвестиОбработкуНаСервере(ИмяФайла) 

              \n

                 Чтение = Новый ЧтениеТекста(ИмяФайла);
                 ...

              \n

                 Результат = Чтение.Прочитать();
                 Возврат Результат;

              \n

              КонецФункции

              \n

              Правильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...

              \n

                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                  НачатьПомещениеФайла(ОписаниеОповещения,,
                         ИмяФайлаДляОбработки,  Ложь,
                         УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаСервере
              Функция ПроизвестиОбработкуНаСервере(Адрес)

              \n

                 Данные = ПолучитьИзВременногоХранилища(Адрес);
                 ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"txt\");
                 Данные.Записать(ИмяПромежуточногоФайла);

              \n

                 Чтение = Новый ЧтениеТекста(ИмяПромежуточногоФайла);
                 ...
                 Результат = Чтение.Прочитать();
                 ...

              \n

                 УдалитьФайлы(ИмяПромежуточногоФайла);  

              \n

                 Возврат Результат;

              \n

              КонецФункции

              \n

              2. Для сохранения данных во временном хранилище между несколькими серверными вызовами, при помещении его в хранилище необходимо использовать параметр УникальныйИдентификаторФормы метода ПоместитьФайл, передав в него идентификатор текущей формы. Такие значения будут удалены из временного хранилища только при закрытии указанной формы. При этом, при повторном помещении того же файла во временное хранилище, предыдущее значение необходимо удалять вручную. Например:

              \n

              Неправильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()

              \n

                 ...
                 // Первый серверный вызов
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиНачальнуюОбработкуНаСервере(Адрес);
                 ПродолжитьОбработкуФайла();
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайла()

              \n

                 ...
                 // Второй серверный вызов с той же версией файла
                 Результат = ПроизвестиПромежуточнуюОбработкуНаСервере(Адрес);
                 ...

              \n

                 // Третий серверный вызов с новой версией файла
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                 \"ПродолжитьОбработкуФайлаЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте

              \n

              Процедура ПродолжитьОбработкуФайлаЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиКонечнуюбОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              При этом во временном хранилище формы останется две копии файлов. Адрес второй копии будет находиться в переменной Адрес, а адрес первой копии будет утерян. Это приводит к затрате дополнительных ресурсов приложения, замедлению работы.

              \n

              Правильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()

              \n

                 ...
                 // Первый серверный вызов
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";  

              \n

                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиНачальнуюОбработкуНаСервере(Адрес);
                 ПродолжитьОбработкуФайла();
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайла()

              \n

                 ...
                 // Второй серверный вызов с той же версией файла
                 Результат = ПроизвестиПромежуточнуюОбработкуНаСервере(Адрес);
                 ...

              \n

                 // Третий серверный вызов с новой версией файла
                 УдалитьИзВременногоХранилища(Адрес);

              \n

                 ОписаниеОповещения = Новый ОписаниеОповещения(
                 \"ПродолжитьОбработкуФайлаЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайлаЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиКонечнуюбОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              3. Если в конфигурацию встроена Библиотека стандартных подсистем для помещения файлов во временное хранилище необходимо использовать процедуры ЗагрузитьФайл и ЗагрузитьФайлы общего модуля ФайловаяСистемаКлиент. Для сохранения данных файла между несколькими серверными вызовами необходимо использовать свойство ИдентификаторФормы параметра ПараметрыЗагрузки:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(\"ОбработатьФайлЗавершение\", ЭтотОбъект);

                 ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
                 ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;
                 ПараметрыЗагрузки.Интерактивно = Ложь;

              \n

                 ФайловаяСистемаКлиент.ЗагрузитьФайл(ОписаниеОповещения,
                 ПараметрыЗагрузки, ИмяФайлаДляОбработки);

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(ПомещенныйФайл, ДополнительныеПараметры)

                 ...
                 Результат = ПроизвестиОбработкуНаСервере(Адрес);
                 ...

              КонецПроцедуры

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "442", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Ошибка выполнения проверки: не удалось получить версию БСП.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "443", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Ошибка выполнения проверки: не удалось получить назначение ролей пользователей.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "444", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Экспортная процедура в модуле с повторным использованием.", +"Description": "

              Использование модулей с повторным использованием возвращаемых значений

              #std724

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Общие модули с повторным использованием возвращаемых значений (далее: кэш) предусмотрены для кэширования результатов работы функций, которые в них размещены - на время сеанса или на время вызова. Их следует применять для экономии вычислительных ресурсов сервера и для минимизации клиент-серверного взаимодействия.

              \n
              \n

              См. также: раздел \"Повторное использование возвращаемых значений\" документации по платформе 1С:Предприятие,
              Использование значений, влияющих на поведение клиентского приложения

              \n

              2. В то же время, чрезмерное (неоправданное) применение общих модулей с повторным использованием возвращаемых значений может приводить к излишнему потреблению памяти.

              \n

              2.1. Недопустимо создать общие модули с повторным использованием, из которых возвращаются данные, вычисление которых выполняется быстрее, чем получение из кэша. Например, строковые константы. Кроме того, что получение строковой константы каждый раз будет работать гораздо быстрее, чем получение ее из общего модуля с повторным использованием, эти данные будут занимать память кэша.
              Например, неправильно размещать в модуле с повторным использованием:

              \n

              Функция ИмяПакетаУправления() Экспорт
                Возврат \"ManagementPackage\";
              КонецФункции

              \n

              Имеет смысл кэшировать данные, полученные из базы данных, внешних источников данных или путем сложных (ресурсоемких) вычислений. Причем в ряде случаев, даже значения, полученные из базы данных, не стоит кэшировать, если выгода от их кэширования – неочевидна. Например, не стоит кэшировать константы (объект метаданных) примитивных типов, поскольку часто они привносят лишь незначительную долю от общего времени выполнения ресурсоемкой операции.

              \n

              2.2. Следует помещать в кэш только такие данные, к которым потом будут часто обращаться.

              \n

              В частности, следует иметь в виду, что кэш не хранит данные вечно. Закэшированное значение будет удалено из кэша через 20 минут после вычисления или через 6 минут после последнего использования (в зависимости от того, что наступит раньше*). Кроме этого значение будет удалено при нехватке оперативной памяти в рабочем процессе сервера, при перезапуске рабочего процесса и при переключении клиента на другой рабочий процесс. Поэтому если никто \"не успел\" воспользоваться данными из кэша, то этот ресурс был потрачен зря.

              \n
              \n

              * Примечание:  конкретные цифры могут варьироваться в зависимости от используемой версии платформы 1С:Предприятие.

              \n

              2.3. Диапазон значений входных параметров функций, размещенных в общих модулей с повторным использованием, не должен быть широким.
              Например, в конфигурации предусмотрена функция, получающая на вход контрагента. Если контрагентов в базе очень много, а сценарий работы пользователей таков, что вероятность того, что кто-то за 5 минут обратится к этому же контрагенту, очень невысокая, то ресурсы будут потрачены впустую. Кроме того, если эту «трату» умножить на количество одновременно работающих пользователей, то бесполезные расходы ресурсов становятся значительными.

              \n

              3. Не следует изменять данные, полученные  из кэша. В противном случае, возможны скрытые ошибки в работе программы, а также бесполезное расходование памяти (ресурсов кэша). Поэтому в качестве возвращаемых значений рекомендуется  использовать значения, состояние которых изменить нельзя, например: ФиксированныйМассив, ФиксированнаяСтруктура.

              \n

              Это ограничение вызвано тем, что кэш возвращает каждый раз не копию объекта, а ссылку на один и тот же объект в памяти. Например, если в массив, который возвращает функция с повторным использованием, при каждом вызове при проведении документов дописывать новое значение, то в результате кэш очень быстро «распухнет». Кроме того, при очередном сбросе кэша, добавленные значения будут потеряны и код, который на них опирался, будет работать некорректно.

              \n

              4. Если в модуле с повторным использованием размещено несколько экспортных функций, которые не только вызываются «снаружи», но и вызывают друг друга, то следует иметь в виду, что результат «внутренних» вызовов не кэшируется.
              Например, если в модуле ОбменДаннымиПовтИсп размещено две экспортных функции:

              \n

              Функция АвтономнаяРаботаПоддерживается() Экспорт
               Возврат ...
              КонецФункции

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              которые последовательно вызываются из прикладного кода,

              \n

              ... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
              ... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();

              \n

              то функция АвтономнаяРаботаПоддерживается будет вычислена дважды.

              \n

              Для того чтобы ее возвращаемое значение всегда получалось из кэша, следует явно указывать имя модуля:

              \n

              Функция ЭтоАвтономноеРабочееМесто() Экспорт
               Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
              КонецФункции

              \n

              5. Если у общего модуля свойство \"Повторное использование возвращаемых значений\" установлено в значение \"На время сеанса\", то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц, Запрос, объекты базы данных (например, ДокументОбъект, ОтчетОбъект) причем, как непосредственно, так и в составе любых коллекций. Ограничение вызвано тем, что значения этих типов допустимо использовать только в том же серверном вызове, в котором они были получены (созданы).

              \n

              Возврат значений этих типов в указанных функциях не проверяется платформой и приводит к трудно диагностируемой остановке работы программы (записи есть только в технологическом журнале).

              Данное ограничение распространяется на использование значений во временном хранилище.
               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "445", +"Type": "BUG", +"Severity": "MINOR", +"Name": "В реквизит формы присвоена нелокализованная строка.", +"Description": "

              Элементы форм: требования по локализации

              #std765

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Нельзя присваивать реквизитам, используемым в элементах формы, строковые значения, не прошедшие локализацию. Рекомендуется для этого использовать, списки значений, в которых для каждого значения задается локализуемое представление, или перечисления, если они используются в таблицах базы данных.

              \n

              Неправильно:

              Если Режим = \"Рабочий\" Тогда\n\u0009Режим = \"Демо\";\nИначе\n\u0009Режим = \"Рабочий\";\nКонецЕсли;\n
              \n

              Правильно:

              \n

              Правильно:

              Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда\n\u0009Режим = Перечисления.РежимыРаботы.Демо;\nИначе\n\u0009Режим = Перечисления.РежимыРаботы.Рабочий;\nКонецЕсли;
               
              \n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Для всех таблиц и групп на формах необходимо указывать заголовки, и, если эти заголовки не нужно показывать пользователю, в свойствах элемента формы в явном виде убирать отображение заголовка элемента.

              \n

              Это требование связано с тем, что, если заголовок не указан, при использовании команды Изменить форму пользователь увидит заголовки, автоматически сгенерированные из имен элементов формы, а перевести их будет невозможно, потому что такие заголовки попадут в выгрузку на перевод как пустые, и переведены не будут.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              \n

              Для автоматической расстановки заголовков можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              3. Следует уменьшать количество незначащей информации, подлежащей локализации.

              \n

              3.1. Удалять бессмысленные подсказки у групп форм. См. стандарт Подсказка и проверка заполнения.

              \n

              Это связано не только со стремлением удешевить перевод, но и с тем, что пользователь может увидеть такие подсказки, например, когда будет изменять форму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              3.2. У реквизитов формы, не размещенных на форме в виде элементов управления, следует очищать заголовки, т.к. они не видны пользователю. Как правило, это служебные реквизиты, используемые для технологических целей.

              \n

              Для удаление бессмысленных подсказок можно воспользоваться обработкой, приложенной к статье Тексты модулей.

              \n

              4. Следует задавать заголовок для колонок динамического списка, получающихся в запросе комбинацией других колонок или для которых задан свой псевдоним. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Например, неправильно:

              \n

              Правильно:

              \n

              Примеры, когда заголовок колонок следует задавать в явном виде:

              \n

              ВЫБРАТЬ
                  Таблица.Поле1 КАК Поле2
                  ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3

              \n

              В таком случае, когда поле создается в запросе и ему присваивается имя, то синоним не \"подтягивается\" автоматически из метаданных, т.к. не существует реквизита, связанного с этим полем. Инструментом редактирования текстов интерфейсов не находится заголовок для колонок в динамическом списке, которым задан псевдоним в запросе. Имя колонки динамического списка должно быть задано, даже если заголовок поля не выводится на форму, так как имена колонок выводятся пользователю при настройке полей формы (команда Еще - Изменить форму...).

              \n

              5. В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина. В этом случае, в поле будет корректно выводиться локализуемое представление, а не значение из списка выбора.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "446", +"Type": "BUG", +"Severity": "MINOR", +"Name": "У элемента формы не заполнен заголовок.", +"Description": "

              Элементы форм: требования по локализации

              #std765

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Нельзя присваивать реквизитам, используемым в элементах формы, строковые значения, не прошедшие локализацию. Рекомендуется для этого использовать, списки значений, в которых для каждого значения задается локализуемое представление, или перечисления, если они используются в таблицах базы данных.

              \n

              Неправильно:

              Если Режим = \"Рабочий\" Тогда\n\u0009Режим = \"Демо\";\nИначе\n\u0009Режим = \"Рабочий\";\nКонецЕсли;\n
              \n

              Правильно:

              \n

              Правильно:

              Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда\n\u0009Режим = Перечисления.РежимыРаботы.Демо;\nИначе\n\u0009Режим = Перечисления.РежимыРаботы.Рабочий;\nКонецЕсли;
               
              \n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Для всех таблиц и групп на формах необходимо указывать заголовки, и, если эти заголовки не нужно показывать пользователю, в свойствах элемента формы в явном виде убирать отображение заголовка элемента.

              \n

              Это требование связано с тем, что, если заголовок не указан, при использовании команды Изменить форму пользователь увидит заголовки, автоматически сгенерированные из имен элементов формы, а перевести их будет невозможно, потому что такие заголовки попадут в выгрузку на перевод как пустые, и переведены не будут.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              \n

              Для автоматической расстановки заголовков можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              3. Следует уменьшать количество незначащей информации, подлежащей локализации.

              \n

              3.1. Удалять бессмысленные подсказки у групп форм. См. стандарт Подсказка и проверка заполнения.

              \n

              Это связано не только со стремлением удешевить перевод, но и с тем, что пользователь может увидеть такие подсказки, например, когда будет изменять форму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              3.2. У реквизитов формы, не размещенных на форме в виде элементов управления, следует очищать заголовки, т.к. они не видны пользователю. Как правило, это служебные реквизиты, используемые для технологических целей.

              \n

              Для удаление бессмысленных подсказок можно воспользоваться обработкой, приложенной к статье Тексты модулей.

              \n

              4. Следует задавать заголовок для колонок динамического списка, получающихся в запросе комбинацией других колонок или для которых задан свой псевдоним. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Например, неправильно:

              \n

              Правильно:

              \n

              Примеры, когда заголовок колонок следует задавать в явном виде:

              \n

              ВЫБРАТЬ
                  Таблица.Поле1 КАК Поле2
                  ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3

              \n

              В таком случае, когда поле создается в запросе и ему присваивается имя, то синоним не \"подтягивается\" автоматически из метаданных, т.к. не существует реквизита, связанного с этим полем. Инструментом редактирования текстов интерфейсов не находится заголовок для колонок в динамическом списке, которым задан псевдоним в запросе. Имя колонки динамического списка должно быть задано, даже если заголовок поля не выводится на форму, так как имена колонок выводятся пользователю при настройке полей формы (команда Еще - Изменить форму...).

              \n

              5. В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина. В этом случае, в поле будет корректно выводиться локализуемое представление, а не значение из списка выбора.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "447", +"Type": "BUG", +"Severity": "MINOR", +"Name": "У элемента формы бессмысленная подсказка.", +"Description": "

              Элементы форм: требования по локализации

              #std765

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Нельзя присваивать реквизитам, используемым в элементах формы, строковые значения, не прошедшие локализацию. Рекомендуется для этого использовать, списки значений, в которых для каждого значения задается локализуемое представление, или перечисления, если они используются в таблицах базы данных.

              \n

              Неправильно:

              Если Режим = \"Рабочий\" Тогда\n\u0009Режим = \"Демо\";\nИначе\n\u0009Режим = \"Рабочий\";\nКонецЕсли;\n
              \n

              Правильно:

              \n

              Правильно:

              Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда\n\u0009Режим = Перечисления.РежимыРаботы.Демо;\nИначе\n\u0009Режим = Перечисления.РежимыРаботы.Рабочий;\nКонецЕсли;
               
              \n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Для всех таблиц и групп на формах необходимо указывать заголовки, и, если эти заголовки не нужно показывать пользователю, в свойствах элемента формы в явном виде убирать отображение заголовка элемента.

              \n

              Это требование связано с тем, что, если заголовок не указан, при использовании команды Изменить форму пользователь увидит заголовки, автоматически сгенерированные из имен элементов формы, а перевести их будет невозможно, потому что такие заголовки попадут в выгрузку на перевод как пустые, и переведены не будут.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              \n

              Для автоматической расстановки заголовков можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              3. Следует уменьшать количество незначащей информации, подлежащей локализации.

              \n

              3.1. Удалять бессмысленные подсказки у групп форм. См. стандарт Подсказка и проверка заполнения.

              \n

              Это связано не только со стремлением удешевить перевод, но и с тем, что пользователь может увидеть такие подсказки, например, когда будет изменять форму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              3.2. У реквизитов формы, не размещенных на форме в виде элементов управления, следует очищать заголовки, т.к. они не видны пользователю. Как правило, это служебные реквизиты, используемые для технологических целей.

              \n

              Для удаление бессмысленных подсказок можно воспользоваться обработкой, приложенной к статье Тексты модулей.

              \n

              4. Следует задавать заголовок для колонок динамического списка, получающихся в запросе комбинацией других колонок или для которых задан свой псевдоним. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Например, неправильно:

              \n

              Правильно:

              \n

              Примеры, когда заголовок колонок следует задавать в явном виде:

              \n

              ВЫБРАТЬ
                  Таблица.Поле1 КАК Поле2
                  ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3

              \n

              В таком случае, когда поле создается в запросе и ему присваивается имя, то синоним не \"подтягивается\" автоматически из метаданных, т.к. не существует реквизита, связанного с этим полем. Инструментом редактирования текстов интерфейсов не находится заголовок для колонок в динамическом списке, которым задан псевдоним в запросе. Имя колонки динамического списка должно быть задано, даже если заголовок поля не выводится на форму, так как имена колонок выводятся пользователю при настройке полей формы (команда Еще - Изменить форму...).

              \n

              5. В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина. В этом случае, в поле будет корректно выводиться локализуемое представление, а не значение из списка выбора.

              \n

              См. также

              \n\n\n\n

              Подсказка и проверка заполнения

              #std478

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.1. Свойство «Подсказка». Задается для тех объектов (реквизитов объектов, реквизитов табличных частей, измерений и ресурсов регистров), которые выводятся пользователю в виде элементов интерфейса и которые требуют пояснения, расшифровки и донесения до пользователя подробного описания их назначения. Для реквизитов, используемых в ежедневной работе, подсказки добавлять не следует.

              \n

              В тексте подсказки не рекомендуется приводить инструкции и объяснять работу реквизита, вместо этого следует оптимизировать сценарии работы, с ним связанные.

              \n

              При этом бессмысленные подсказки, автоматические генерируемые конфигуратором при создании элементов управления (групп) на формах, нужно не забывать очищать. Например, «Группа шапка» и пр.

              \n
              \n

              См. также: Подсказки на форме, Подсказки для интерфейсных подсистем, Тексты

              \n

              2.1. Свойство «Проверка заполнения». Для всех типизированных объектов метаданных, а также для стандартных реквизитов и табличных частей, которые в соответствии с логикой объекта являются обязательными к заполнению, свойство \"Проверка заполнения\" должно быть установлено в \"Выдавать ошибку\".

              В ряде случаев проведение документа с незаполненными реквизитами и табличными частями не имеет смысла с точки зрения отражения документа в учете. Например, документ Заказ клиента является запросом клиента на поставку определенного количества товара. Из определения понятно, что методически заказ с незаполненным клиентом и незаполненной табличной частью Товары не имеет смысла, поэтому у реквизита Клиент и табличной части Товары свойство \"Проверка заполнения\" должно быть установлено в \"Выдавать ошибку\".

              \n

              2.2. При установке свойства «Проверка заполнения» следует исходить из того, что все ограничения и проверки должны быть (насколько это возможно полно) описаны в метаданных конфигурации. Поэтому если хотя бы один из сценариев работы с объектом требует обязательного заполнения реквизита, то свойство «Проверка заполнения» устанавливается в «Выдавать ошибку». Если в других сценариях работы заполнять реквизит не обязательно, то такие случаи должны быть предусмотрены в обработчике события модуля объекта ОбработкаПроверкиЗаполнения.

              \n

              При этом не следует придерживаться обратной схемы, когда свойство «Проверка заполнения» установлено в «Не проверять», а в обработчике ОбработкаПроверкиЗаполнения дописаны какие-либо проверки заполнения. Такая схема затрудняет анализ логики работы конфигурации.

              \n

              2.3. Если проверка заполнения реквизита зависит от тех или иных условий, рекомендуется управлять автопометкой незаполненного значения с помощью условного оформления форм объектов. Убирать ее в случае, если при данном состоянии объекта заполнение реквизита проверять не требуется.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "448", +"Type": "BUG", +"Severity": "MINOR", +"Name": "У элемента формы с заполненным списком выбора отключено свойство \"Режим выбора из списка\".", +"Description": "

              Элементы форм: требования по локализации

              #std765

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Нельзя присваивать реквизитам, используемым в элементах формы, строковые значения, не прошедшие локализацию. Рекомендуется для этого использовать, списки значений, в которых для каждого значения задается локализуемое представление, или перечисления, если они используются в таблицах базы данных.

              \n

              Неправильно:

              Если Режим = \"Рабочий\" Тогда\n\u0009Режим = \"Демо\";\nИначе\n\u0009Режим = \"Рабочий\";\nКонецЕсли;\n
              \n

              Правильно:

              \n

              Правильно:

              Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда\n\u0009Режим = Перечисления.РежимыРаботы.Демо;\nИначе\n\u0009Режим = Перечисления.РежимыРаботы.Рабочий;\nКонецЕсли;
               
              \n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Для всех таблиц и групп на формах необходимо указывать заголовки, и, если эти заголовки не нужно показывать пользователю, в свойствах элемента формы в явном виде убирать отображение заголовка элемента.

              \n

              Это требование связано с тем, что, если заголовок не указан, при использовании команды Изменить форму пользователь увидит заголовки, автоматически сгенерированные из имен элементов формы, а перевести их будет невозможно, потому что такие заголовки попадут в выгрузку на перевод как пустые, и переведены не будут.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              \n

              Для автоматической расстановки заголовков можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              3. Следует уменьшать количество незначащей информации, подлежащей локализации.

              \n

              3.1. Удалять бессмысленные подсказки у групп форм. См. стандарт Подсказка и проверка заполнения.

              \n

              Это связано не только со стремлением удешевить перевод, но и с тем, что пользователь может увидеть такие подсказки, например, когда будет изменять форму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              3.2. У реквизитов формы, не размещенных на форме в виде элементов управления, следует очищать заголовки, т.к. они не видны пользователю. Как правило, это служебные реквизиты, используемые для технологических целей.

              \n

              Для удаление бессмысленных подсказок можно воспользоваться обработкой, приложенной к статье Тексты модулей.

              \n

              4. Следует задавать заголовок для колонок динамического списка, получающихся в запросе комбинацией других колонок или для которых задан свой псевдоним. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Например, неправильно:

              \n

              Правильно:

              \n

              Примеры, когда заголовок колонок следует задавать в явном виде:

              \n

              ВЫБРАТЬ
                  Таблица.Поле1 КАК Поле2
                  ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3

              \n

              В таком случае, когда поле создается в запросе и ему присваивается имя, то синоним не \"подтягивается\" автоматически из метаданных, т.к. не существует реквизита, связанного с этим полем. Инструментом редактирования текстов интерфейсов не находится заголовок для колонок в динамическом списке, которым задан псевдоним в запросе. Имя колонки динамического списка должно быть задано, даже если заголовок поля не выводится на форму, так как имена колонок выводятся пользователю при настройке полей формы (команда Еще - Изменить форму...).

              \n

              5. В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина. В этом случае, в поле будет корректно выводиться локализуемое представление, а не значение из списка выбора.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "449", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Задано наименование предопределенного регламентного задания.", +"Description": "

              Регламентные задания: требования по локализации

              #std767

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Предопределенным регламентным заданиям не следует задавать наименования в конфигураторе. Вместо этого, достаточно задать синоним предопределенного регламентного задания.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              Для непредопределенных (параметризованных) регламентных заданий наименование задается программно, оформляется с НСтр и может описывать контекст выполнения задания.

              \n

              Правильно:

              Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.РассылкаОтчетов);\nЗадание.Наименование = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Рассылка отчетов: %1'\"), РассылкаОтчетов);\nЗадание.Записать();
              \n

              Это связано с тем, что в отсутствие наименования платформа возьмет его автоматически из локализуемого синонима. Если же наименование задано, то будет использоваться оно, а оно не поддерживает локализацию.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "450", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В макете используется кодировка, отличная от \"UTF-8\".", +"Description": "

              Макеты: требования по локализации и поддержке разных языков интерфейса

              #std766

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Как правило, перевод табличных, текстовых и HTML-макетов на другие языки не требует каких-либо подготовительных действий при разработке конфигурации. Особым случаем являются двоичные макеты, подлежащие переводу, а также HTML-макеты, содержащие изображения, которые должны быть отдельно подготовлены на разных языках. Например, это двоичные макеты печатных форм в форматах офисных документов, HTML-макеты с инструкциями, включающие скриншоты интерфейса программы или изображения, содержащие текстовую информацию.

              \n

              Такой макет необходимо пометить специальным образом, пометка будет означать, что при переводе будет необходимо создавать копию, а не переводить содержимое макета. Для этого в имени макета следует указывать постфикс в виде подчеркивания и кода языка так, как он задан в метаданных, в языке Русский в свойстве Код языка: \"_ru\".
              Например, неправильно:

              \n

              макет ПФ_ODT_СчетНаОплату (макет печатной формы счета на оплату в формате OpenOffice Writer)

              \n

              правильно указывать в имени постфикс основного языка:

              \n

              макет ПФ_ODT_СчетНаОплату_ru

              \n

              При добавлении языков интерфейса следует добавлять макеты с соответствующими постфиксами. В коде, в зависимости от языка, использовать макет с соответствующим постфиксом. Например, неправильно:

              ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\");\n
              \n

              правильно:

              \n

              ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\" +  \"_\" + ТекущийЯзык());

              \n

              Кроме того, для исключения ошибок при частичном переводе конфигурации, рекомендуется выполнять получение макета в три этапа:

              \n
                \n
              • Сначала по ИмяМакета + \"_\" + ТекущийЯзык(); \n
              • Если не найден, то по ИмяМакета + \"_\" + Метаданные.ОсновнойЯзык.КодЯзыка; \n
              • Если не найден, то по переданному имени ИмяМакета. \n
              • И наконец установить свойство КодЯзыка (у табличного документа) или КодЯзыкаМакета (у текстового документа и HTML-макета), как указано далее в п.2.
              \n

              2. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может возникнуть задача в одном сеансе пользователя формировать печатные формы на разных языках, а не только на текущем языке интерфейса. Например, в сеансе англоязычного пользователя сформировать счет на оплату на русском языке.

              \n

              Для получения данных из табличного, текстового или HTML-макета на заданном языке, отличном от языка интерфейса текущего пользователя, необходимо использовать свойство КодЯзыка (доступно у табличного документа) и КодЯзыкаМакета (у текстового документа и HTML-макета).

              \n

              Правильно:

              Макет = ПолучитьОбщийМакет(\"ПечатнаяФорма\");\nМакет.КодЯзыкаМакета = \"ru\";\nHTMLДокумент = Макет.ПолучитьДокументHTML();\n
              \n

              3. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может также возникнуть задача формировать печатные формы строго на одном языке, не зависимо от текущего языка интерфейса. Примером таких макетов могут служить регламентированные формы отчетности для государственных учреждений. Например, пользователи с любым языком интерфейса должны формировать русскоязычную счет-фактуру – налоговый документ строго установленного образца в соответствии с Налоговым кодексом Российской Федерации (не существует российских счет-фактур на других языках, кроме русского).

              \n

              Для табличных и HTML-макетов, которые должны выводится пользователю и на печать строго на одном языке, следует

              \n
                \n
              • указывать в наименовании постфикс кода языка, аналогично п.1 \n
              • и устанавливать код языка макета аналогично п.2 при программном получении макета в коде.
              \n

              Такие макеты не должны переводиться на другие языки интерфейса. При программном формировании текстов для заполнения макета следует явно указывать второй параметр в функции НСтр() для того, чтобы строки были сформированы на том же языке, что и макет.

              \n

              Например, не правильно:

              Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура\");\n...\nОбласть.Текст = НСтр(\"ru='Заголовок печати';\");\n
              \n

              Правильно:

              \n

              Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура_ru\");
              Макет.КодЯзыка = Метаданные().Языки.Русский.КодЯзыка;
              ...
              Область.Текст = НСтр(\"ru='Заголовок печати';\", Метаданные().Языки.Русский.КодЯзыка);

              \n

              При использовании Библиотеки стандартных подсистем (БСП) и подсистемы Печать получение макета через функцию УправлениеПечатью.МакетПечатнойФормы(\"ПФ_MXL_СчетФактура\") позволяет получить форму ПФ_MXL_СчетФактура_ru и устанавливает у макета свойство КодЯзыка.

              \n

              4. Если в текстах макетов используются именованные параметры подстановки, необходимо соблюдать для них требования по локализации интерфейсных текстов в коде.

              \n

              5. Кодировку в макетах использовать UTF-8.

              \n

              6. Также, по возможности, следует группировать однотипные макеты (использовать один макет вместо нескольких). Например, в следующем примере в конфигурации имеется несколько однотипных макетов с сообщениями, но их содержимое записывается в один справочник, поэтому правильно хранить все подобные сообщения в одном макете.

              \n

              Неправильно:

               
              Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(\"Сообщение\");\n
              \n

              Правильно:

              \n

               

              Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(\"Сообщения_%1\", ОбщегоНазначения.КодОсновногоЯзыка()));
              \n

              7. Внешние компоненты следует размешать в макетах с типом макета внешняя компонента. При разработке внешней компоненты требуется обрабатывать метод SetLocale для локализации внешней компоненты в соответствии с полученным кодом локализации (см. Технология создания внешних компонент). Если полученный код локализации отличается от предусмотренного во внешней компоненте, то компонента должна настроить свое окружение на использование английского языка.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "453", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Обращение к менеджеру регламентных заданий при наличии подсистемы \"Технология сервиса\".", +"Description": "

              Ограничения на регламентные задания при работе в режиме сервиса

              #std760

              Область применения: управляемое приложение.

              \n

              1. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть регламентных заданий, которые включены в состав любого из разделителей. Это ограничение обусловлено тем, что при большом количестве областей данных в одной информационной базе разделенные регламентные задания могут вызвать перегрузку рабочих процессов, обслуживающих данную информационную базу, и серьезно затруднить работу пользователей сервиса.

              \n

              2. Если требуется обеспечить регулярное выполнение определенного программного кода в каждой области данных разделенной информационной базы, необходимо использовать подсистему БСП «Очередь заданий», либо разработать аналогичный механизм очереди заданий самостоятельно.

              Например, требуется добавить в конфигурацию регламентное задание ПроверкаЦен, которое должно по расписанию выполнять в каждой области проверку прайс-листов, сопоставлять цены с динамикой валютных курсов, и при необходимости формировать некие сообщения для пользователей.

              Неправильно:

              Добавить в конфигурацию регламентное заданий ПроверкаЦен и включить его в состав общего реквизита ОбластьДанныхОсновныеДанные.

              Правильно:

              \n
                \n
              • \n
                Реализовать прикладную функциональность проверки. Предположим, это будет процедура ПроверитьЦены модуля УправлениеЦенами.
                \n
              • \n
                Добавить в конфигурацию предопределенное неразделенное регламентное задание ПроверкаЦен. Установить в качестве обработчика процедуру УправлениеЦенами.ПроверитьЦены.
                \n
              • \n
                Добавить в общий модуль ОчередьЗаданийПереопределяемый следующий программный код:
              \n

              Процедура ПриПолученииСпискаШаблонов(Шаблоны) Экспорт
                      Шаблоны.Добавить(Метаданные.РегламентныеЗадания.ПроверкаЦен.Имя);
              КонецПроцедуры

              Процедура ПриОпределенииПсевдонимовОбработчиков(СоответствиеИменПсевдонимам) Экспорт
                      СоответствиеИменПсевдонимам.Вставить(Метаданные.РегламентныеЗадания.ПроверкаЦен.ИмяМетода);
              КонецПроцедуры

              \n

              3. Единственным исключением является ситуация, когда регламентное задание обязательно должно выполняться от имени определенного пользователя. Например, может потребоваться, чтобы при выполнении задания учитывались установленные для пользователя ограничения доступа к данным. В этом случае разделение регламентного задания допускается, но такое задание обязательно должно быть включено в состав всех разделителей, определенных в конфигурации.

              \n

              4. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть участков, где из программного кода напрямую выполняется управление регламентными заданиями. Для управления регламентными заданиями необходимо использовать программный интерфейс БСП, реализованный в модуле РегламентныеЗаданияСервер.

              Неправильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              НашеЗадание.Использование = Истина;
              НашеЗадание.Записать();

              \n

              Правильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗаданияСервер.НайтиЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              Параметры = Новый Структура();
              Параметры.Вставить(“Использование”, Истина);
              РегламентныеЗаданияСервер.ИзменитьЗадание(НашеЗадание.УникальныйИдентификатор, Параметры);

              \n

              5. Следует учитывать, что подсистема «Очередь заданий» не гарантирует выполнение регламентного задания в точном соответствии с указанным расписанием. Точность соблюдения расписания зависит от общего количества запланированных заданий, длительности их выполнения и количества исполняющих потоков (регулируется константой «Максимальное количество исполняющихся фоновых заданий»).
              Рекомендуется в общем случае при работе в режиме сервиса не предоставлять пользователям возможность настройки расписания регламентных заданий.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "454", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Регламентное задание включено в состав разделителя.", +"Description": "

              Ограничения на регламентные задания при работе в режиме сервиса

              #std760

              Область применения: управляемое приложение.

              \n

              1. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть регламентных заданий, которые включены в состав любого из разделителей. Это ограничение обусловлено тем, что при большом количестве областей данных в одной информационной базе разделенные регламентные задания могут вызвать перегрузку рабочих процессов, обслуживающих данную информационную базу, и серьезно затруднить работу пользователей сервиса.

              \n

              2. Если требуется обеспечить регулярное выполнение определенного программного кода в каждой области данных разделенной информационной базы, необходимо использовать подсистему БСП «Очередь заданий», либо разработать аналогичный механизм очереди заданий самостоятельно.

              Например, требуется добавить в конфигурацию регламентное задание ПроверкаЦен, которое должно по расписанию выполнять в каждой области проверку прайс-листов, сопоставлять цены с динамикой валютных курсов, и при необходимости формировать некие сообщения для пользователей.

              Неправильно:

              Добавить в конфигурацию регламентное заданий ПроверкаЦен и включить его в состав общего реквизита ОбластьДанныхОсновныеДанные.

              Правильно:

              \n
                \n
              • \n
                Реализовать прикладную функциональность проверки. Предположим, это будет процедура ПроверитьЦены модуля УправлениеЦенами.
                \n
              • \n
                Добавить в конфигурацию предопределенное неразделенное регламентное задание ПроверкаЦен. Установить в качестве обработчика процедуру УправлениеЦенами.ПроверитьЦены.
                \n
              • \n
                Добавить в общий модуль ОчередьЗаданийПереопределяемый следующий программный код:
              \n

              Процедура ПриПолученииСпискаШаблонов(Шаблоны) Экспорт
                      Шаблоны.Добавить(Метаданные.РегламентныеЗадания.ПроверкаЦен.Имя);
              КонецПроцедуры

              Процедура ПриОпределенииПсевдонимовОбработчиков(СоответствиеИменПсевдонимам) Экспорт
                      СоответствиеИменПсевдонимам.Вставить(Метаданные.РегламентныеЗадания.ПроверкаЦен.ИмяМетода);
              КонецПроцедуры

              \n

              3. Единственным исключением является ситуация, когда регламентное задание обязательно должно выполняться от имени определенного пользователя. Например, может потребоваться, чтобы при выполнении задания учитывались установленные для пользователя ограничения доступа к данным. В этом случае разделение регламентного задания допускается, но такое задание обязательно должно быть включено в состав всех разделителей, определенных в конфигурации.

              \n

              4. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть участков, где из программного кода напрямую выполняется управление регламентными заданиями. Для управления регламентными заданиями необходимо использовать программный интерфейс БСП, реализованный в модуле РегламентныеЗаданияСервер.

              Неправильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              НашеЗадание.Использование = Истина;
              НашеЗадание.Записать();

              \n

              Правильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗаданияСервер.НайтиЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              Параметры = Новый Структура();
              Параметры.Вставить(“Использование”, Истина);
              РегламентныеЗаданияСервер.ИзменитьЗадание(НашеЗадание.УникальныйИдентификатор, Параметры);

              \n

              5. Следует учитывать, что подсистема «Очередь заданий» не гарантирует выполнение регламентного задания в точном соответствии с указанным расписанием. Точность соблюдения расписания зависит от общего количества запланированных заданий, длительности их выполнения и количества исполняющих потоков (регулируется константой «Максимальное количество исполняющихся фоновых заданий»).
              Рекомендуется в общем случае при работе в режиме сервиса не предоставлять пользователям возможность настройки расписания регламентных заданий.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "455", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Регламентное задание с включенным использованием отсутствует в процедуре \"ОчередьЗаданийПереопределяемый.ПриПолученииСпискаШаблонов\".", +"Description": "

              Ограничения на регламентные задания при работе в режиме сервиса

              #std760

              Область применения: управляемое приложение.

              \n

              1. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть регламентных заданий, которые включены в состав любого из разделителей. Это ограничение обусловлено тем, что при большом количестве областей данных в одной информационной базе разделенные регламентные задания могут вызвать перегрузку рабочих процессов, обслуживающих данную информационную базу, и серьезно затруднить работу пользователей сервиса.

              \n

              2. Если требуется обеспечить регулярное выполнение определенного программного кода в каждой области данных разделенной информационной базы, необходимо использовать подсистему БСП «Очередь заданий», либо разработать аналогичный механизм очереди заданий самостоятельно.

              Например, требуется добавить в конфигурацию регламентное задание ПроверкаЦен, которое должно по расписанию выполнять в каждой области проверку прайс-листов, сопоставлять цены с динамикой валютных курсов, и при необходимости формировать некие сообщения для пользователей.

              Неправильно:

              Добавить в конфигурацию регламентное заданий ПроверкаЦен и включить его в состав общего реквизита ОбластьДанныхОсновныеДанные.

              Правильно:

              \n
                \n
              • \n
                Реализовать прикладную функциональность проверки. Предположим, это будет процедура ПроверитьЦены модуля УправлениеЦенами.
                \n
              • \n
                Добавить в конфигурацию предопределенное неразделенное регламентное задание ПроверкаЦен. Установить в качестве обработчика процедуру УправлениеЦенами.ПроверитьЦены.
                \n
              • \n
                Добавить в общий модуль ОчередьЗаданийПереопределяемый следующий программный код:
              \n

              Процедура ПриПолученииСпискаШаблонов(Шаблоны) Экспорт
                      Шаблоны.Добавить(Метаданные.РегламентныеЗадания.ПроверкаЦен.Имя);
              КонецПроцедуры

              Процедура ПриОпределенииПсевдонимовОбработчиков(СоответствиеИменПсевдонимам) Экспорт
                      СоответствиеИменПсевдонимам.Вставить(Метаданные.РегламентныеЗадания.ПроверкаЦен.ИмяМетода);
              КонецПроцедуры

              \n

              3. Единственным исключением является ситуация, когда регламентное задание обязательно должно выполняться от имени определенного пользователя. Например, может потребоваться, чтобы при выполнении задания учитывались установленные для пользователя ограничения доступа к данным. В этом случае разделение регламентного задания допускается, но такое задание обязательно должно быть включено в состав всех разделителей, определенных в конфигурации.

              \n

              4. В прикладных решениях, ориентированных на работу в режиме сервиса по Технологии 1cFresh, не должно быть участков, где из программного кода напрямую выполняется управление регламентными заданиями. Для управления регламентными заданиями необходимо использовать программный интерфейс БСП, реализованный в модуле РегламентныеЗаданияСервер.

              Неправильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              НашеЗадание.Использование = Истина;
              НашеЗадание.Записать();

              \n

              Правильно:

              \n

              // Ищем задание по наименованию.
              Отбор = Новый Структура();
              Отбор.Вставить(“Метаданные”, “ПроверкаЦен”);
              Задания = РегламентныеЗаданияСервер.НайтиЗадания(Отбор);

              \n

              // Проверяем, что задание найдено.
              Если Задания.Количество() <> 1 Тогда
               // Запись в журнал ошибки опущена.
               Возврат;
              КонецЕсли;

              \n

              // Включаем найденное задание.
              НашеЗадание = Задания[0];
              Параметры = Новый Структура();
              Параметры.Вставить(“Использование”, Истина);
              РегламентныеЗаданияСервер.ИзменитьЗадание(НашеЗадание.УникальныйИдентификатор, Параметры);

              \n

              5. Следует учитывать, что подсистема «Очередь заданий» не гарантирует выполнение регламентного задания в точном соответствии с указанным расписанием. Точность соблюдения расписания зависит от общего количества запланированных заданий, длительности их выполнения и количества исполняющих потоков (регулируется константой «Максимальное количество исполняющихся фоновых заданий»).
              Рекомендуется в общем случае при работе в режиме сервиса не предоставлять пользователям возможность настройки расписания регламентных заданий.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "456", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использование метода \"СтрШаблон()\".", +"Description": "

              Ограничение на использование метода \"СтрШаблон()\" в коде модулей

              \r\n
              \r\n

              Область применения: управляемое приложение, обычное приложение.

              \r\n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.

              \r\n

              Методическая рекомендация (полезный совет)

              \r\n

              Для подстановки параметров в строку разработчику следует использовать метод СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(). Метод СтрШаблон() применять не следует.

              \r\n

              Например, в модуле конфигурации есть следущий код:

              \r\n

              ШаблонТекста = НСтр(\"ru='Первый параметр %1, второй параметр %2'\");
              Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекста, 1, 2);

              \r\n

              Избавимся от прослойки вызовов и лишних методов с помощью метода СтрШаблон():

              \r\n

              ШаблонТекста = НСтр(\"ru='Первый параметр %1, второй параметр %2'\");
              Текст = СтрШаблон(ШаблонТекста, 1, 2);

              \r\n

              Конфигурация не всегда сразу полностью переводится на другой язык. И, если в системе будет работать пользователь, у которого будет установлен язык не RU, то первый код отработает корректно, а второй выдаст ошибку исполнения.

              \r\n

              Во втором случае локализованной строки нет, следовательно, параметров в строке нет, следовательно, возникает ошибка исполнения.

              \r\n

              В связи с этим, в модулях конфигураций принято решение не использовать СтрШаблон() до исправления ошибки платформы.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "457", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка видимости в командном интерфейсе конфигурации.", +"Description": "

              Проверка прав доступа

              #std737

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

              \n
                \n
              • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
              • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
              \n

              Эти меры позволяют:

              \n
                \n
              • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
              • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
              • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
              \n

              2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

              \n

              3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
              Например, неправильно:

              \n

              Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
              Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

              \n

              правильно:

              \n

              Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
              Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

              \n

              Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

              \n

              4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
              Например, без использования БСП:

              \n

              Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

              \n

              Либо аналогичная проверка с использованием БСП:

              \n

              Если Пользователи.РолиДоступны(...) Тогда ...

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "458", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Устаревшая процедура (функция) расположена вне области \"УстаревшиеПроцедурыИФункции\".", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "459", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Описание процедуры (функции) размещено в середине, а не в начале комментария; либо описание параметра без отступа.", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "460", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка видимости в рабочей области начальной страницы.", +"Description": "

              Проверка прав доступа

              #std737

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

              \n
                \n
              • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
              • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
              \n

              Эти меры позволяют:

              \n
                \n
              • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
              • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
              • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
              \n

              2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

              \n

              3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
              Например, неправильно:

              \n

              Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
              Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

              \n

              правильно:

              \n

              Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
              Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

              \n

              Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

              \n

              4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
              Например, без использования БСП:

              \n

              Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

              \n

              Либо аналогичная проверка с использованием БСП:

              \n

              Если Пользователи.РолиДоступны(...) Тогда ...

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "461", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована ролевая настройка видимости в командном интерфейсе основного раздела.", +"Description": "

              Проверка прав доступа

              #std737

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

              \n
                \n
              • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
              • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
              \n

              Эти меры позволяют:

              \n
                \n
              • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
              • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
              • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
              \n

              2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

              \n

              3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
              Например, неправильно:

              \n

              Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
              Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

              \n

              правильно:

              \n

              Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
              Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

              \n

              Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

              \n

              4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
              Например, без использования БСП:

              \n

              Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

              \n

              Либо аналогичная проверка с использованием БСП:

              \n

              Если Пользователи.РолиДоступны(...) Тогда ...

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "462", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Для строковой константы запроса СКД не установлено представление доступного значения.", +"Description": "

              Запросы, динамические списки и отчеты на СКД: требования по локализации

              #std762

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

              \n

              Неправильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
              \n

              Также неправильно:

              ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              Правильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

              \n

              а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

              \n

              б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

              \n

              Неправильно:

              ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
              \n

              Правильно:

              ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
              \n

              в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

              \n

              Неправильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
              \n

              Правильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
              \n

              3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "463", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Строковая константа в запросе СКД не соответствует правилам образования имен переменных.", +"Description": "

              Запросы, динамические списки и отчеты на СКД: требования по локализации

              #std762

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

              \n

              Неправильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
              \n

              Также неправильно:

              ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              Правильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

              \n

              а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

              \n

              б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

              \n

              Неправильно:

              ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
              \n

              Правильно:

              ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
              \n

              в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

              \n

              Неправильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
              \n

              Правильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
              \n

              3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "464", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Не заполнен заголовок поля динамического списка.", +"Description": "

              Элементы форм: требования по локализации

              #std765

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Нельзя присваивать реквизитам, используемым в элементах формы, строковые значения, не прошедшие локализацию. Рекомендуется для этого использовать, списки значений, в которых для каждого значения задается локализуемое представление, или перечисления, если они используются в таблицах базы данных.

              \n

              Неправильно:

              Если Режим = \"Рабочий\" Тогда\n\u0009Режим = \"Демо\";\nИначе\n\u0009Режим = \"Рабочий\";\nКонецЕсли;\n
              \n

              Правильно:

              \n

              Правильно:

              Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда\n\u0009Режим = Перечисления.РежимыРаботы.Демо;\nИначе\n\u0009Режим = Перечисления.РежимыРаботы.Рабочий;\nКонецЕсли;
               
              \n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. Для всех таблиц и групп на формах необходимо указывать заголовки, и, если эти заголовки не нужно показывать пользователю, в свойствах элемента формы в явном виде убирать отображение заголовка элемента.

              \n

              Это требование связано с тем, что, если заголовок не указан, при использовании команды Изменить форму пользователь увидит заголовки, автоматически сгенерированные из имен элементов формы, а перевести их будет невозможно, потому что такие заголовки попадут в выгрузку на перевод как пустые, и переведены не будут.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              \n

              Для автоматической расстановки заголовков можно воспользоваться обработкой автоформатирования кода и локализации.

              \n

              3. Следует уменьшать количество незначащей информации, подлежащей локализации.

              \n

              3.1. Удалять бессмысленные подсказки у групп форм. См. стандарт Подсказка и проверка заполнения.

              \n

              Это связано не только со стремлением удешевить перевод, но и с тем, что пользователь может увидеть такие подсказки, например, когда будет изменять форму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              3.2. У реквизитов формы, не размещенных на форме в виде элементов управления, следует очищать заголовки, т.к. они не видны пользователю. Как правило, это служебные реквизиты, используемые для технологических целей.

              \n

              Для удаление бессмысленных подсказок можно воспользоваться обработкой, приложенной к статье Тексты модулей.

              \n

              4. Следует задавать заголовок для колонок динамического списка, получающихся в запросе комбинацией других колонок или для которых задан свой псевдоним. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Например, неправильно:

              \n

              Правильно:

              \n

              Примеры, когда заголовок колонок следует задавать в явном виде:

              \n

              ВЫБРАТЬ
                  Таблица.Поле1 КАК Поле2
                  ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3

              \n

              В таком случае, когда поле создается в запросе и ему присваивается имя, то синоним не \"подтягивается\" автоматически из метаданных, т.к. не существует реквизита, связанного с этим полем. Инструментом редактирования текстов интерфейсов не находится заголовок для колонок в динамическом списке, которым задан псевдоним в запросе. Имя колонки динамического списка должно быть задано, даже если заголовок поля не выводится на форму, так как имена колонок выводятся пользователю при настройке полей формы (команда Еще - Изменить форму...).

              \n

              5. В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина. В этом случае, в поле будет корректно выводиться локализуемое представление, а не значение из списка выбора.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "465", +"Type": "BUG", +"Severity": "MINOR", +"Name": "Не заполнен заголовок поля выборки в запросе СКД.", +"Description": "

              Запросы, динамические списки и отчеты на СКД: требования по локализации

              #std762

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

              \n

              Неправильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
              \n

              Также неправильно:

              ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              Правильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

              \n

              а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

              \n

              б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

              \n

              Неправильно:

              ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
              \n

              Правильно:

              ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
              \n

              в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

              \n

              Неправильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
              \n

              Правильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
              \n

              3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "466", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Нестандартные секции в описании экспортной процедуры (функции).", +"Description": "

              Описание процедур и функций

              #std453

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Описание процедур и функций рекомендуется выполнять в виде комментария к ним. Необходимость комментирования отдельных участков кода процедур и функций должна определяться разработчиком исходя из сложности и нестандартности конкретного участка кода.

              \n

              При разработке на платформе 1С:Предприятие 8.3 текст комментария также выводится в контекстной подсказке процедур, функций и их параметров. Подробнее см. раздел «Контекстная подсказка при вводе текстов модулей» главы 27 «Инструменты разработки» в документации к платформе.

              \n

              При разработке в 1C:Enterprise Development Tools текст комментария также используется для уточнения типизации параметров и возвращаемого значения процедур и функций, и тем самым помогает выявлять ошибки кодирования на этапе разработки.

              \n

              2. Обязательного комментирования требуют процедуры и функции входящие в программный интерфейс модулей - такие процедуры и функции предназначены для использования в других функциональных подсистемах (или в других приложениях), за которые могут отвечать другие разработчики, поэтому они должны быть хорошо документированы.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций и Использование экспортных процедур и функций в модулях форм

              \n

              3. Прочие процедуры и функции (в том числе обработчики событий модулей форм, объектов, наборов записей, менеджеров значений и т.п.) рекомендуется комментировать, если требуется пояснить назначение процедуры (функции) или особенности её работы. Также рекомендуется описывать причины невыполнения некоторых действий, если они кажутся неочевидными для данной процедуры или функции.

              \n

              Но если процедура (функция) не сложна для понимания и ее назначение и порядок работы следуют из ее названия и имен формальных параметров, комментарий допускается не писать.

              \n

              4.  Следует избегать комментариев, не дающих дополнительных пояснений о работе не-экспортной процедуры (функции).
              Например, неправильно:

              // Процедура - обработчик события \"ПриОткрытии\" формы\n//\n&НаКлиенте\nПроцедура ПриОткрытии()\n\n// Процедура-обработчик команды \"Рассчитать\"\n//\n&НаКлиенте\nПроцедура Рассчитать()\n\n// Процедура-обработчик события \"ПриИзменении\" элемента формы \"РедактированиеТолькоВДиалоге\"\n//\n&НаКлиенте\nПроцедура РедактированиеТолькоВДиалогеПриИзменении(Элемент)\n
              \n

              В этих примерах комментарии избыточны, так как из названий процедур очевидно, что это обработчики событий. А с их описанием и назначением параметров можно ознакомиться в синтакс-помощнике.

              // Функция возвращает статью движения денежных средств по данным документа\nФункция СтатьяДвиженияДенежныхСредств(ДанныеДокумента)\n
              \n

              Этот комментарий не дает никакой дополнительной информации о функции.

              \n

              5. Комментарий размещается перед объявлением процедуры (функции) и имеет следующий вид.

              5.1. Секция \"Описание\" (англ. \"Description\")  содержит описание назначения процедуры (функции), достаточное для понимания сценариев ее использования без просмотра ее исходного кода. Также может содержать краткое описание принципов работы и перекрестные ссылки на связанные процедуры и функции.

              \n

              Может быть единственной секцией для процедур без параметров. Описание не должно совпадать с именем процедуры (функции). Для процедур и функций секция должна начинаться с глагола. Для функций это, как правило: «Возвращает…». В тех случаях, когда возвращаемый результат является не основным в работе функции, – то с основного действия, например: «Проверяет…», «Сравнивает…», «Вычисляет…» и т.п. Не рекомендуется начинать описание с избыточных слов «Процедура...», «Функция...», а также с имени самой процедуры (функции), от удаления которых смысл не меняется.

              \n

              Например, неправильно:

              // Конструктор объекта WSПрокси.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Функция СтрокаТаблицыЗначенийВСтруктуру создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              Правильно:

              // Создает прокси на основе определения веб-сервиса и связывает\n// его с точкой подключения веб-сервиса.\n// В дополнении к платформенному конструктору Новый WSПрокси:\n//  - включает в себя вызов конструктора WSОпределения;\n//  - на время сеанса кэширует файл WSDL для оптимизации частых обращений к веб-сервису;\n//  - не требует явного указания ИнтернетПрокси (он подставляется автоматически, если настроен);\n//  - выполняет быструю проверку доступности веб-сервиса с помощью операции Ping.\n// ...\nФункция WSПрокси(ПараметрыПрокси) Экспорт\n\n// Создает структуру со свойствами, соответствующими...\nФункция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт\n
              \n

              5.2. Секция \"Параметры\" (англ. \"Parameters\")  описывает параметры процедуры (функции). Если их нет, секция пропускается. Предваряется строкой \"Параметры:\", затем с новой строки размещаются описания всех параметров.

              \n

              5.2.1. Описание параметра начинается с новой строки, далее имя параметра, затем дефис и список типов (*), далее дефис и текстовое описание параметра.

              \n

              Имя параметра необходимо стремиться выбирать таким образом, чтобы его назначение было понятно в контексте функции без дополнительных пояснений

              \n

              Описание типа является обязательным. Тип может быть описан явно, при этом может быть указан или один тип или список типов. Под «списком типов» подразумеваются имена типов, разделенные запятыми. Имя типа может быть простым (в одно слово) или составным - в два слова, разделенных точкой.
              Например: Строка, Структура, Произвольный, СправочникСсылка.Сотрудники.

              \n

              Кроме того, не следует использовать в качестве типов значений несуществующие в платформе типы.

              \n

              Например, неправильно:

              // КоллекцияСтрок - КоллекцияЗначений – коллекция для сравнения;\n
              \n

              Правильно:

              // КоллекцияСтрок – ТаблицаЗначений, Массив, СписокЗначений – Элемент для сравнения.\n
              \n

              Текстовое описание параметра рекомендуется заполнять в том случае, когда только имени параметра в контексте функции не достаточно для понимания его назначения, либо требуется дать дополнительную информацию о типе, поясняющие назначение параметра, а также может приводиться наглядный пример с ожидаемым значением параметра.

              \n

              Например, неправильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Строка - Строка - строка, содержащая электронные адреса
              //  ЗадачаСсылка  - ЗадачаСсылка.ЗадачаИсполнителя – проверяемая задача
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              Правильно:

              \n

              // Проверяет, что переданные адреса включены в задачу. Если проверка не проходит – генерируется исключение.
              //
              // Параметры:
              //  Адреса - Строка - содержит электронные адреса, разделенные запятой. Например, \"support@mycorp.ru,v8@localdomain\"
              //  Задача - ЗадачаСсылка.ЗадачаИсполнителя
              //
              Процедура ПроверитьАдресаЗадачи(Адреса, ЗадачаИсполнителя)

              \n

              В данном примере текстовое описание для параметра «Адреса» нужно чтобы

              \n
                \n
              • указать правило передачи нескольких адресов (через зяпятую) \n
              • привести пример
              \n

              Текстовое описание для параметра «Задача» не нужно.

              \n

              5.2.2. Для параметров типа Структура и ТаблицаЗначений также задается описание их свойств и колонок, которые начинаются с новой строки и предваряются символом *.
              Например:

              // Параметры:\n//   СтатусыСерий - ТаблицаЗначений - таблица с колонками:\n//     * Серия - СправочникСсылка.СерииНоменклатуры - если серия указана и она может\n//               использоваться с новым значением номенклатуры на указанном складе, \n//               то возвращается переданное значение; если нет - пустая ссылка\n//     * СтатусУказанияСерий - Число - если серии указываются в ТЧ \"Товары\", то \n//               возвращается рассчитанный статус, если для переданной\n//               номенклатуры/склада серии не используется - возвращается 0\n//               иначе возвращается переданный статус.\n
              \n

              5.2.3. Для параметров типа Массив следует указывать тип элементов с помощью ключевого слова \"из\" (англ. \"contains\"):

              \n

              Например, неправильно:

              // МассивПеренаправленныхЗадач - Массив - массив перенаправленных задач.
              // МассивПеренаправленныхЗадач - Массив - задачи (ЗадачаСсылка.ЗадачаИсполнителя), перенаправленные другому исполнителю.
              \n

              Правильно:

              // ПеренаправленныеЗадачи - Массив из ЗадачаСсылка.ЗадачаИсполнителя

              // СведенияОбОбновлении - Массив из Структура - содержит:\n// * КодАдресногоОбъекта - Строка\n// * Наименование - Строка\n// * Индекс - Строка\n// * ОбновлениеДоступно - Булево\n//
              \n

              В описании массивов, структур и таблиц значений могут быть вложенные описания, при этом перед именами вложенных свойств число звездочек увеличивается: для первого уровня вложенности 2 звездочки, для второго 3 и т.д.

              // Параметры:\n//  СведенияОбОбновлении - Массив из Структура - содержит:\n//     * КодАдресногоОбъекта - Структура - содержит:\n//        ** КодРегиона             - Число - код региона (длина - 2).\n//        ** КодНаселенногоПункта   - Число - код населенного пункта (длина - 3).\n//        ** КодУлицы               - Число - код улицы (длина - 4).\n//     * Наименование        - Строка\n//     * ОбновлениеДоступно  - Булево\n//
              \n

              5.2.4. Также для каждого параметра можно задать одно или несколько дополнительных описаний типов параметра. Каждое дополнительное описание начинается с новой строки, затем обязательный дефис, далее список типов параметра далее дефис и текстовое описание.
              Например:

              // Параметры:\n//   Реквизиты - Строка - имена реквизитов, перечисленные через запятую.\n//                        Например, \"Код, Наименование, Родитель\".\n//             - Структура, ФиксированнаяСтруктура - в качестве ключа передается\n//                        псевдоним поля для возвращаемой структуры с результатом,\n//                        а в качестве значения (опционально) фактическое имя поля в таблице.\n//                        Если значение не определено, то имя поля берется из ключа.\n//             - Массив, ФиксированныйМассив - имена реквизитов (Строка).\n
              \n

              5.2.5. Описание также могут быть заданы с помощью ссылки на функцию-конструктор в формате \"см. ПутьКФункции\" (англ \"see MethodPath\").

              \n

              Например:

              //   ПараметрыУказанияСерий - см. НоменклатураКлиентСервер.ПараметрыУказанияСерий
              \n// РеквизитыКомпонент - Массив из см. ВнешниеКомпонентыСлужебный.РеквизитыКомпоненты\n
              \n

              5.3. Секция \"Возвращаемое значение\" (англ. \"Returns\") описывает тип и содержание возвращаемого значения функции. Для процедур эта секция отсутствует. Предваряется строкой \"Возвращаемое значение:\". Затем с новой строки тип возвращаемого значения, дефис и текст описания. При использовании возвращаемого значения составного типа следует каждый тип писать с новой строки и с дефиса. Например:

              // Возвращаемое значение:\n//  Строка\n\n// Возвращаемое значение:\n//  Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю, либо у него есть административные права.\n\n// Возвращаемое значение: \n//  - ЛюбаяСсылка - ссылка на предопределенный элемент.\n//  - Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.\n\n// Возвращаемое значение:\n//  - СправочникСсылка.Пользователи\n//  - СправочникСсылка.ВнешниеПользователи
              \n

              Текстовое описание возвращаемого значения рекомендуется заполнять в том случае, когда только одного описания функции не достаточно, либо требуется дать дополнительную информацию о типе, например, о составе свойств или колонок возвращаемого значения. Также может быть приведен пример с ожидаемым значением возвращаемого значения, либо сквозной пример размещается в секции \"Пример\" ниже.

              \n

              Для возвращаемых значений также действуют требования п.5.2.2 и 5.2.3.

              \n

              5.4. Секция \"Пример\" (англ. \"Example\") содержит пример использования процедуры, или функции. Предваряется строкой \"Пример:\". Далее с новой строки пример использования. Имя процедуры (функции) следует писать вместе с именем общего модуля, в котором она расположена. Из примера должно быть понятно, что передается на входе и что возвращается на выходе.
              Например, неправильно:

              // Пример:\n//  ПодставитьПараметрыВСтроку(ШаблонСтроки, СтрокаЗамены);\n
              \n

              Правильно:

              // Пример:\n//  СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru='%1 пошел в %2'\"), \"Вася\", \"Зоопарк\") = \"Вася пошел в Зоопарк\".\n
              \n

              5.4.1. В переопределяемых модулях в секции \"Пример\" следует размещать пример реализации переопределяемой процедуры, а не пример ее вызова. Например, для процедуры ПриОпределенииОбщихПараметровБазовойФункциональности(ОбщиеПараметры):

              // Пример:\n//  ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = \"8.3.4.365\";\n//  ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти = 2;\n
              \n

              5.5. В редких случаях, когда сразу несколько параметров имеют дополнительные типы, рекомендуется добавить секцию \"Варианты вызова\" (англ. \"Сall options\"), в которой дать описания наиболее частых или всех возможных вариантов вызова функции с различными комбинациями типов параметров. Секция начинается фразой \"Варианты вызова:\" с новой строки, затем идут описания вариантов, каждое начинается с новой строки. Каждый вариант вызова представляется в виде имени функции со списком типов, перечисленных через запятую в круглых скобках, затем следует дефис и текстовое описание варианта.

              \n

              Например:

              // ...\n//\n// Параметры:\n//   Параметр1 - Тип11, Тип12        - ...\n//   Параметр2 - Тип21, Тип22, Тип23 - ...\n//\n// Варианты вызова:\n//   УниверсальнаяПроцедура(Тип11, Тип21) - описание ...\n//   УниверсальнаяПроцедура(Тип12, Тип22) - описание ...\n//   УниверсальнаяПроцедура(Тип11, Тип23) - описание ...\n//\nПроцедура УниверсальнаяПроцедура(Параметр1, Параметр2) Экспорт\n
              \n

              5.6. В любом месте документирующего комментария можно добавить переход к другим объектам конфигурации, процедурам и функциям (в частности, для перехода к функциям-конструкторам структур). При использовании 1C:Enterprise Development Tools среда оформит такие переходы в виде гиперссылки.
              Например:

              // Описание универсальной процедуры.\n// \n// См. УправлениеДоступом.ЗаполнитьНаборыЗначенийДоступа\n//\n// Параметры:\n//   Параметр1 – Произвольный – описание параметра см. Справочник.Контрагенты.\n//\nПроцедура УниверсальнаяПроцедура(Параметр1)\n
              \n

              5.7. В случаях когда возникает необходимость отметить процедуру (функцию) как устаревшую, в первой строке ее описания размещается слово \"Устарела\" (англ. \"Deprecated\")..
              Например:

              // Устарела. Следует использовать новую см. ОбщегоНазначения.ЕстьРоль\n// ... \nФункция РолиДоступны(ИменаРолей) Экспорт\n
              \n

              6. Если требуется прокомментировать процедуру или функцию с директивой компиляции, то вначале следует размещать комментарий, а затем -
              директиву компиляции. Например:

              // Процедура - обработчик события \"ПриСозданииНаСервере\" формы.\n// Обрабатывает параметры формы и заполняет реквизиты формы значениями.\n// А также выполняет следующие действия:\n// ...\n//\n&НаСервере\nПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)\n
              \n

              Такой стиль размещения комментария позволяет в первую очередь обращать внимание на определение функции и директиву компиляции, а потом - на комментарий, который может занимать достаточно большое количество строк.

              \n

              7. Код процедур и функций должен отделяться друг от друга в тексте модуля пустыми строками.

              \n

              Примеры описания процедур и функций

              \n

              Пример описания функции с одним параметром:

              // Определяет доступность ролей ИменаРолей текущему пользователю,\n// а также доступность административных прав.\n//\n// Параметры:\n//   ИменаРолей - Строка - имена ролей, доступность которых проверяется, разделенные запятыми.\n//\n// Возвращаемое значение:\n//   Булево - Истина, если хотя бы одна из переданных ролей доступна текущему пользователю,\n//   либо у него есть административные права.\n//\n// Пример:\n// Если РолиДоступны(\"ИспользованиеРассылокОтчетов,ОтправкаПоПочте\") Тогда ...\n//\nФункция РолиДоступны(ИменаРолей) Экспорт \n
              \n

              Пример описания процедуры без параметров:

              // В обработчике события ПередЗаписью документа выполняется;\n// - очистка табличной части услуги, в случае если указан договор с комиссионером;\n// - проверка заполнения реквизита ЕдиницаИзмеренияМест табл. части Товары;\n// - синхронизация с \"подчиненным\" счетом-фактурой;\n// - заполнение склада и заказа покупателя в табличных частях Товары и ВозвратнаяТара;\n// - удаление неиспользуемых строк табличной части \"Серийные номера\";\n// - заполнение переменной модуля объекта УдалятьДвижение.\n//\nПроцедура ПередЗаписью() \n\nКонецПроцедуры
               
              \n\n\n\n
              \n

              Для автоматического упорядочивания комментариев к процедурам или функциям с директивами компиляции можно воспользоваться приложенной обработкой ФорматированиеДирективКомпиляции.epf.

              \n

              Для этого необходимо:

              \n
                \n
              1. Выгрузить модули конфигурации (команда меню Конфигурация -> Выгрузить файлы конфигурации...) \n
              2. Открыть обработку в режиме 1С:Предприятие и указать каталог, в который были выгружены модули - далее нажать кнопку \"Форматировать\" \n
              3. Загрузить модули в конфигурацию (команда меню Конфигурация -> Загрузить файлы конфигурации...)
              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 10 +}, +{ +"Code": "467", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использование монопольного или оперативного обработчика обновления.", +"Description": "lang=RU link=blue vlink=purple style='tab-interval:35.4pt'>\n\n
              \n\n

              Ограничения на использование монопольного и\nоперативного режимов обработчиков обновления

              \n\n

              Область применения: управляемое приложение.

              \n\n

              Действует для «корпоративных» конфигураций (например, 1С:ERP), и\nвсех входящих в них библиотек.

              \n\n

              1.\nИз-за большого объема данных в пользовательских базах, переход на новый релиз\nможет занимать очень длительное время. Поэтому для сокращения времени простоя\nпри обновлении конфигурации следует полностью отказаться от монопольных и\nоперативных обработчиков обновления.

              \n\n

              Вместо\nэтого, большие объемы данных следует обновлять отложенно – см. Параллельный режим отложенного\nобновления (БСП). Исключением являются случаи, описанные ниже.

              \n\n

              2.1.\nДопустимо делать оперативную или монопольную обработку данных только при\nсоблюдении всех, перечисленных\nниже условий:

              \n\n
                \n
              • объем\n обрабатываемых данных всегда (у всех пользователей) будет небольшой, время\n их обработки будет измеряться минутами;
              • \n
              • обрабатываемые\n данные – это нормативно-справочная информация, без обработки которой\n работа большей части пользователей будет невозможна, сильно затруднена или\n с большой долей вероятности приведет к некорректному состоянию\n информационной базы. При этом все-таки нужно стремиться и нормативно-справочную\n информацию также обрабатывать отложенно;
              • \n
              • обработчик\n может вызываться только при обновлении на конкретную версию, не должно\n быть обработчиков, которые вызываются при каждом обновлении.
              • \n
              \n\n

              2.2.\nОперативный обработчик следует делать, если обновляемый объект метаданных не\nбудет реструктуризироваться в процессе применения изменений конфигурации к\nинформационной базе. В противном случае с точки зрения пользователей нет\nразницы в работе оперативных и монопольных обработчиков.

              \n\n

              2.3.\nДопустимо делать оперативную обработку данных:

              \n\n
                \n
              • для обновления\n настроек программы (в частности значений констант), если объем\n обрабатываемых данных небольшой;
              • \n
              • и для\n обновления неразделенных данных, для которых технически отложенное\n обновление не поддерживается.
              • \n
              \n\n

              2.4.\nИспользование оперативного или монопольного режимов работы обработчиков\nобновления в библиотеках должно быть индивидуально согласовано со всеми\nконечными конфигурациями, в которые эти библиотеки входят в рамках стандартной\nпроцедуры согласования изменения стандартов и перечислены в приложении к\nстандарту.

              \n\n

              Приложение: список исключений

              \n\n

              1.  Библиотека стандартных подсистем

              \n\n

              1.1.\nВыполняются оперативно, т.к. объем обрабатываемых данных небольшой (обновление\nнастроек программы):

              \n\n

              ·        \nВариантыОтчетов.ОперативноеОбновлениеРазделенныхДанныхКонфигурации\n(*, Условно подключаемый в модели сервиса);

              \n\n

              ·        \nРаботаСФайламиСлужебный.ОбновитьСписокЗапрещенныхРасширенийВОбластиДанных\n(2.3.2.70, Начальное заполнение);

              \n\n

              ·        \nУдалениеПомеченныхОбъектовСлужебный.ВключитьУдалениеПомеченныхОбъектов\n(2.3.5.52, Начальное заполнение);

              \n\n

              ·        \nУправлениеСвойствами.ОбновитьНаименованияНаборовИСвойств (*,\nУсловно подключаемый).

              \n\n

              1.2. Выполняются\nоперативно, т.к. обновляются неразделенные данные:

              \n\n

              ·        \nВариантыОтчетов.ОперативноеОбновлениеОбщихДанныхКонфигурации (*);

              \n\n

              ·        \nВариантыОтчетов.ОтложенноеОбновлениеОбщихДанныхКонфигурацииПолное\n(*, только в модели сервиса, в «коробке» - отложенно);

              \n\n

              ·        \nДатыЗапретаИзмененияСлужебный.ОбновитьРазделыДатЗапретаИзменения\n(*);

              \n\n

              ·        \nДатыЗапретаИзмененияСлужебный.ОчиститьПредопределенныеЭлементыРазделовДатЗапрета\n(2.3.5.9);

              \n\n

              ·        \nКалендарныеГрафики.ОбновитьДанныеПроизводственныхКалендарей\n(2.3.5.28, Начальное заполнение);

              \n\n

              ·        \nПодключаемыеКоманды.ОперативноеОбновлениеОбщихДанныхКонфигурации\n(*);

              \n\n

              ·        \nПользователиСлужебный.ДобавитьАдминистраторамПравоОткрытияВнешнихОтчетовИОбработок\n(2.3.5.14);

              \n\n

              ·        \nРаботаСФайламиСлужебный.ОбновитьСписокЗапрещенныхРасширений (2.3.4.5,\nНачальное заполнение);

              \n\n

              ·        \nРаботаСФайламиСлужебный.ОбновитьПутьТомаLinux (2.3.5.48).

              \n\n

              1.3. Выполняются оперативно для удаления устаревших\nотложенных обработчиков обновления (до начала отложенного обновления):

              \n\n

              ·        \nВариантыОтчетов.УдалитьУстаревшиеОбработчики (2.3.5.19);

              \n\n

              1.4.\nВыполняются оперативно для планирования обновления областей данных в модели\nсервиса (в коробке не выполняются):

              \n\n

              ·        \nОбменДаннымиВМоделиСервиса.ЗаполнитьОбработчикиРазделенныхДанных\n(*, Управление обработчиками);

              \n\n

              ·        \nУправлениеДоступомСлужебный.ЗаполнитьОбработчикиРазделенныхДанных\n(*, Управление обработчиками);

              \n\n

              ·        \nУправлениеСвойствамиСлужебный.ЗаполнитьОбработчикиРазделенныхДанных\n(*, Управление обработчиками).

              \n\n

              1.5. Выполняются оперативно для изменения свойств\nрегламентных заданий, настроек прав доступа, которые должны обязательно вступить\nв силу до начала работы с программой:

              \n\n

              ·        \nОбработки.ЗагрузкаКлассификатораБанков.УстановитьРасписаниеРегламентногоЗадания\n(2.3.5.51, Начальное заполнение);

              \n\n

              ·        \nОбработки.ЗагрузкаКурсовВалют.УстановитьРасписаниеРегламентногоЗадания\n(2.3.5.51, Начальное заполнение);

              \n\n

              ·        \nУдалениеПомеченныхОбъектовСлужебный.ВключитьУдалениеПомеченныхОбъектов\n(2.3.5.52, Начальное заполнение);

              \n\n

              ·        \nУправлениеДоступомСлужебный.ОбновитьВспомогательныеДанныеПоИзменениямКонфигурации\n(*, Условно подключаемый);

              \n\n

              ·        \nУправлениеДоступомСлужебный.ОбновитьДанныеПрофиляОткрытиеВнешнихОтчетовИОбработок\n(2.3.5.33);

              \n\n

              ·        \nУправлениеИтогамиИАгрегатамиСлужебный.ОбновитьИспользованиеРегламентныхЗаданий\n(2.3.3.70, Начальное заполнение);

              \n\n

              ·        \nУправлениеПечатью.ДобавитьРольРедактированиеПечатныхФормВПрофилиСБазовымиПравами\n(2.3.5.3).

              \n\n

              1.6.\nДо запуска механики обновления информационной базы выполняется оперативное\nобновление следующих неразделенных кешей метаданных\n(только если связанные с ними метаданные были изменены):
              \n- в РИБ выполняется загрузка предопределенных элементов и идентификаторов\nобъектов метаданных из главного узла
              \n  (ОбменДаннымиСервер.ЗагрузитьПриоритетныеДанныеВПодчиненныйУзелРИБ)
              \n- Справочник.ИдентификаторыОбъектовМетаданных
              \n- РегистрСведений.ПараметрыРаботыПрограммы 

              \n- РегистрСведений.ПраваРолей
              \n- РегистрСведений.ЗависимостиПравДоступа

              \n\n

              1.7.\nЗаполняются оперативно, чтобы не откладывать до входа пользователя в сеанс:
              \n- Справочник.ИдентификаторыОбъектовРасширений
              \n- РегистрСведений.ИдентификаторыОбъектовВерсийРасширений
              \n- РегистрСведений.ПараметрыРаботыВерсийРасширений
              \n- Справочник.ПредопределенныеВариантыОтчетовРасширений
              \n- РегистрСведений.ПредопределенныеВариантыОтчетовВерсийРасширений

              \n\n

              1.8.\nСтандартныеПодсистемыСервер.УстановитьКонстантуНеИспользоватьРазделениеПоОбластямДанных\nусловно-монопольный: выполняется в монопольном режиме только если у\nнеразделенных констант

              \n\n

              ·        \nИспользоватьРазделениеПоОбластямДанных;

              \n\n

              ·        \nНеИспользоватьРазделениеПоОбластямДанных;

              \n\n

              ·        \nЭтоАвтономноеРабочееМесто

              \n\n

              установлены\nнесинхронные значения.
              \nИх значения влияют на те механизмы конфигурации, которые по-разному работают в\nэтих режимах.

              \n\n

              1.9.\nОбменДаннымиСервер.ВыполнитьОбновлениеПравилДляОбменаДанными:\nвыполняется оперативно при каждом обновлении при условии использования\nсинхронизации данных. Объем обрабатываемых данных не большой: выполняется\nобновление кеша правил конвертации и правил\nрегистрации. 
              \nПеренос выполнения данного обработчика на более поздний момент может привести к\nнегативным последствиям, связанным с применением неактуальных (предназначенных\nдля предыдущей версии) алгоритмов регистрации данных в случае изменения или\nдобавления данных: 

              \n\n

              ·        \nпри выполнении других обработчиков\nобновления; 

              \n\n

              ·        \nпри работе пользователей в программе. 

              \n\n

              Например,\nесли в новой версии был переименован один из объектов метаданных, участвующих в\nсинхронизации, то попытка пользователя отредактировать соответствующие данные\nбудет приводить к ошибке в момент их записи в информационную базу.

              \n\n

              1.10.\nИнформацияПриЗапуске.ОперативноеОбновлениеОбщихДанных\n(*) выполняется оперативно для обновления неразделенных данных (кеша с рекламой), т.к. реклама должна открываться сразу же\nпосле перехода на новую версию программы.

              \n\n

              1.11\nДатыЗапретаИзмененияСлужебный.ЗаменитьРазделыДатЗапретаНаНовые\n(2.3.5.10) выполняется монопольно, так как до выполнения новые пользователи\nмогут получить доступ к закрытым периодам, а после выполнения старые\nпользователи могут получить доступ к закрытым периодам.

              \n\n

               

              \n\n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "468", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Экспортная процедура (функция) в области \"ПрограммныйИнтерфейс\" в общем модуле с повторным использованием.", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "469", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В служебном общем модуле присутствует область \"ПрограммныйИнтерфейс\".", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "470", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Превышена максимальная длина числовых данных в запросе (31 знак).", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "472", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Небезопасное подключение внешних компонент.", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "473", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Область \"ДляВызоваИзДругихПодсистем\" не входит в область \"ПрограммныйИнтерфейс\".", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "474", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В комментарии внутри области \"ДляВызоваИзДругихПодсистем\" не указана подсистема-потребитель.", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "475", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В комментарии внутри области \"ДляВызоваИзДругихПодсистем\" указана несуществующая подсистема.", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "476", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Внутри области \"ДляВызоваИзДругихПодсистем\" не найден закрывающий комментарий \"// Конец ... <имя подсистемы-потребителя>\".", +"Description": "

              Обеспечение совместимости библиотек

              #std644

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При разработке библиотек необходимо обеспечивать обратную совместимость (далее просто: совместимость) между различными версиями библиотек в пределах одной подредакции библиотеки.

              \n

              Например, версии библиотеки 2.0.1, 2.0.2 и 2.0.5 должны быть совместимы. Однако допустимо, если следующая редакция 2.1 будет содержать существенные изменения, нарушающие это правило.

              \n

              Совместимость версий библиотек позволяет существенно минимизировать затраты на обновление библиотеки в конфигурациях-потребителях, так как не требует от прикладных разработчиков многократно пересматривать код и адаптировать объекты метаданных своих конфигураций под изменения библиотеки. Прикладное решение может «уверенно» использовать старые возможности библиотеки, не «торопясь» переходить на новые.

              \n

              Кроме того, при разработке нескольких библиотек, стоящих на поддержке друг у друга, совместимость позволяет вести совместную разработку «соседних» библиотек на разных версиях базовой библиотеки, без необходимости частого обновления всего дерева библиотек.

              \n

              1.1. Таким образом, полный номер версии библиотеки однозначно указывает на характер изменений и совместимость с ее предыдущими версиями:

              \n

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Что изменилось в новой версии?РР.ПП.ВВ.СС
              Архитектурные изменения,
              нарушена совместимость
              (есть инструкция по переходу)
              vvxx
              Новые функцииvvvx
              Исправлены ошибкиvvvv

              \n

              Здесь:

              \n
                \n
              1. РР (редакция) – существенно нарушена совместимость (серьезные архитектурные или «знаковые» изменения в библиотеке); \n
              2. ПП (номер подредакции) – нарушена совместимость (требуется отработать инструкцию по переходу на эту версию, иначе конфигурация будет неработоспособна); \n
              3. ВВ (номер версии) – доступны только новые функции для пользователей и/или разработчиков (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель; инструкция по переходу на эту версию не обязательна, без ее отработки конфигурация сохранит работоспособность); \n
              4. СС (номер сборки) – содержит только исправление ошибок (возможна «механическая» автозаливка метаданных библиотеки в конфигурацию-потребитель).
              \n

              Исключением являются заранее согласованные с потребителями библиотеки случаи, такие как отработка изменений законодательства. При отработке изменений законодательства (вступающего в силу до публикации следующей версии) следует выпускать исправительные сборки с этими изменениями для всех веток, находящихся на поддержке, даже если эти изменения добавляют новые функции или нарушают совместимость. В таких случаях вынужденное нарушение обратной совместимости должно быть отражено в сопроводительной документации согласно п.1.8, отработка которой обязательна.

              \n

              1.2. В библиотеках с несколькими функциональными подсистемами нарушение совместимости хотя бы в одной подсистеме означает увеличение номера подредакции библиотеки (2-я цифра).

              \n

              1.3. При незапланированном нарушении совместимости в 3-й и 4-й цифре следует отозвать релиз библиотеки, устранить нарушение и выпустить новый исправленный релиз.

              \n

              1.4. Аналогичные требования распространяются и на незапланированное добавление новых функций в 4-й цифре.

              \n

              1.5. В целях обеспечения совместимости следует

              \n
                \n
              • выделить программный интерфейс библиотеки, скрыв от потребителей все остальные детали ее реализации; \n
              • и не изменять программный интерфейс и поведение. Его допустимо только расширять.
              \n

              Требования обеспечения обратной совместимости имеют приоритет над следующими стандартами разработки:

              \n\n

              1.6. К программному интерфейсу библиотеки относятся те ее объекты метаданных, которые предназначены для использования в прикладном коде:

              \n
                \n
              • имена, состав параметров и поведение экспортных процедур и функций, которые размещены в разделе «программный интерфейс»;  \n
              • имена, состав параметров и поведение всех экспортных процедур переопределяемых общих модулей; \n
              • имена объектов метаданных (включая их реквизиты, табличные части и пр.), к которым допускается непосредственное обращение из прикладного кода или из запросов.
              \n

              1.7. Совместимость не нарушает расширение программного интерфейса библиотеки, т.е. в 3-й цифре допустимо, например:

              \n
                \n
              • добавление новой функции в программный модуль;  \n
              • добавление процедуры в переопределяемый модуль; \n
              • добавление еще одного необязательного параметра в конец списка формальных параметров существующей функции; \n
              • добавление нового реквизита в справочник, регистр и т.п. (к которым библиотека допускает прямые обращения).
              \n

              В то же время:

              \n
                \n
              • Добавления нового API и расширение состава параметров существующего API не ожидают от исправительных релизов библиотеки (поэтому недопустимо в 4-й цифре); \n
              • Даже если состав параметров и название процедуры не меняется, но изменилось ее поведение, то это является нарушение совместимости (т.е. допустимо только во 2-й цифре) \n
                  \n
                • например, процедура Сумма(а, б) вместо суммы вдруг стала вычислять разность.
              \n

              1.8. В остальных случаях, когда согласно п.1 допустимо отказаться от поддержки совместимости, следует документировать в сопроводительной документации к библиотеке любые изменения, приводящие к нарушению совместимости. Документация должна включать инструкцию для прикладных разработчиков по адаптации своих конфигураций к новому программному интерфейсу библиотеки.
              Примеры фрагментов документации:

              \n
                \n
              • Общий модуль ВнешниеЗадачиПереопределяемыйВызовСервера переименован в ВнешниеЗадачиВызовСервераПереопределяемый. Необходимо заменить все обращения к этому модулю в коде конфигурации. \n
              • Процедура УстановитьПроизвольныйЗаголовокПриложения общего модуля СтандартныеПодсистемыКлиент переименована в УстановитьРасширенныйЗаголовокПриложения. Необходимо заменить все обращения к этой процедуре в коде конфигурации. \n
              • Отчет СправкаПоИсполнительскойДисциплине удален. Вместо него следует использовать одноименный вариант отчета Задачи. Необходимо заменить все обращения к этому отчету в коде и в метаданных конфигурации. \n
              • В общий модуль ЗащитаПерсональныхДанныхПереопределяемый добавить процедуру ДополнитьДанныеОрганизацииОператораПерсональныхДанных, перенеся ее определение из поставки библиотеки. \n
              • Хранение предмета взаимодействий перенесено из реквизита документа в реквизит Предмет регистра сведений ПредметыПапкиВзаимодействий. Необходимо заменить все обращения к реквизиту Предмет документов взаимодействий на реквизит Предмет регистра сведений.
              \n

              1.9. Рекомендуется размещать программный интерфейс библиотеки только в ее общих модулях, а не в модулях объектов, менеджеров, наборов записей и т.п.

              \n

              2.1. Для разделения программного интерфейса от служебных процедур и функций необходимо размещать их в разных разделах модуля или в разных общих модулях.

              \n

              При размещении в разных общих модулях, к модулям со служебными процедурами и функциями может быть добавлен постфикс Служебный (англ. Internal).
              Например:

              \n
                \n
              • Общие модули ОбменСообщениями и ОбменСообщениямиКлиент – программный интерфейс подсистемы «Обмен сообщениями» \n
              • Общий модуль ОбменСообщениямиСлужебный – служебные процедуры и функции подсистемы, которые не предназначены для использования в коде конфигурации-потребителя.
              \n

              Такое размещение программного интерфейса в отдельных общих модулях позволяет

              \n
                \n
              • сосредоточить весь программный интерфейс библиотеки в относительно небольшом, обозримом количестве общих модулей,  \n
              • а также выводить в контекстной подсказке при вводе текстов модулей только те процедуры и функции, которые действительно являются частью программного интерфейса. Например, после точки в строке «ОбменСообщениями.» в редакторе текста модуля  разработчик конфигурации-потребителя увидит только то, что ему действительно может понадобиться в работе.
              \n

              2.2. Раздел Программный интерфейс так же может содержать в себе процедуры и функции, предназначенные для вызова конкретными потребителями из других функциональных подсистем библиотеки или из других библиотек. Такие процедуры и функции рекомендуется выделять в отдельный подраздел Для вызова из других подсистем, оформленный в виде области ДляВызоваИзДругихПодсистем (англ. InterfaceImplementation). 

              \n

              Внутри подраздела процедуры и функции должны быть разделены на группы комментариями с именем потребителя, для которого они предназначены. Подробнее см. Разработка конфигураций с повторным использованием общего кода и объектов метаданных. Например:

              \n

              #Область ПрограммныйИнтерфейс
              //Код процедур и функций

              \n

              #Область ДляВызоваИзДругихПодсистем

              \n

              // СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
              // Код процедур и функций
              // Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов

              \n

              // ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
              // Код процедур и функций
              // Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных

              \n

              #КонецОбласти

              \n

              #КонецОбласти

              \n

              Англоязычный вариант синтаксиса:

              \n

              #Region Public
              // Enter code here.

              \n

              #Region InterfaceImplementation

              \n

              // StandardSubsystems.BatchObjectModification
              // Enter code here.
              // End StandardSubsystems.BatchObjectModification

              \n

              // SaaSTechnology.DataExportImport
              // Enter code here.
              // End SaaSTechnology.DataExportImport

              \n

              #EndRegion

              \n

              #EndRegion

              \n

              3. Для обеспечения совместимости программного интерфейса библиотеки в условиях активного развития ее функциональности ниже приведен ряд практических рекомендаций.

              \n

              3.1. При необходимости переименовать (или удалить) экспортную функцию (процедуру) следует оставить прежнюю реализацию функции, пометив ее как устаревшую с помощью комментария вида:

              \n

              // Устарела: Следует использовать функцию ПересчитатьПоКурсу
              // …
              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              (англоязычный аналог \"Устарела\" в начале комментария - \"Deprecated\")

              \n

              и разместить новую версию функции с новым именем (в данном примере - ПересчитатьПоКурсу).

              \n

              При этом устаревшую функцию следует перенести в область общего модуля УстаревшиеПроцедурыИФункции (англ. Deprecated), которая размещена внутри области ПрограммныйИнтерфейс. В процедурах и функциях, размещенных в области УстаревшиеПроцедурыИФункции, допустимы отклонения от других стандартов разработки согласно п.1.1.

              \n

              В этом случае, существующий прикладной код не потребуется переписывать. При этом, если при выпуске новой редакции библиотеки будет принято решение удалить все устаревшие функции, то такие функции могут быть легко выявлены в коде библиотеки и удалены.

              \n

              По каждой устаревшей функции в сопроводительной документации к библиотеке также даются рекомендации по их замене следующего вида:

              \n
                \n
              • Процедура ПересчитатьИзВалютыВВалюту общего модуля ОбщегоНазначения устарела, вместо нее следует использовать ПересчитатьПоКурсу. Устаревшая функция оставлена для обратной совместимости.
              \n

              3.2. В ряде случаев даже при исправлении ошибки, которое поменяло поведение экспортной функции (процедуры), рекомендуется оставлять прежнюю ошибочную функцию, пометив ее как устаревшую, и размещать исправленную версию функции с новым именем. Это позволяет обеспечить работоспособность того прикладного кода, который ранее заложился на неправильное поведение, но работает корректно. При этом его немедленная переработка нецелесообразна или вообще нежелательна (например, в силу большого количества мест вызовов).

              \n

              Более того, может быть крайне нежелательным изменение поведения даже в нештатных и незадокументированных случаях вызова экспортной функции (процедуры).

              \n

              Например, вызывающий код при некорректных значениях входных параметров функции API ожидает (обрабатывает) незадокументированное возвращаемое значение Неопределено, а в новой версии библиотеки эта функция была исправлена и стала вызывать исключение в этом случае. Несмотря на то, что новое поведение спроектировано как более корректное и даже стало задокументированным, это может привести к массовым ошибкам во всех местах ее вызова.

              \n

              3.3. При необходимости пересмотреть состав параметров экспортных функций (процедур) следует использовать опциональные параметры, которые добавляются в конец списка формальных параметров.
              Например:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПоКратностьНач = 1, ПоКратностьКон = 1) Экспорт

              \n

              При этом в случае большого числа параметров рекомендуется предусмотреть последний параметр типа Структура, состав свойств которой можно безболезненно расширять в дальнейшем:

              \n

              Функция ПересчитатьИзВалютыВВалюту(Сумма, ВалютаНач, ВалютаКон, ПоКурсуНач, ПоКурсуКон, ПараметрыПересчета = Неопределено) Экспорт

              \n

              Такой подход рекомендуется использовать заблаговременно в тех процедурах и функциях, где с высокой степенью вероятности ожидается увеличение количества параметров и режимов работы.

              \n

              3.4. Параметры типа Структура применимы и для сохранения совместимости программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. Например, процедура переопределяемого модуля ПриОпределенииНастроек позволяет библиотеке добавлять новые режимы работы без потери совместимости:

              \n

              Процедура ПриОпределенииНастроек(Настройки) Экспорт
               Настройки.ВыводитьОписания = Истина;
               Настройки.События.ПриСозданииНаСервере = Истина;
               Настройки.... = ...;
              КонецПроцедуры

              \n

              Кроме того, этот подход позволяет также сохранять совместимость программного интерфейса, через который библиотека обращается к объектам конфигурации-потребителя. В примере выше строка «Настройки.События.ПриСозданииНаСервере = Истина;» означает, что в конфигурации-потребителя определен одноименный обработчик события библиотеки, который следует вызывать из библиотеки. При этом появление нового события в следующей версии библиотеки не потребует обязательного добавления его пустых обработчика во всех конфигурациях-потребителях. Аналогичным образом, платформа 1С:Предприятие не требует вставлять пустые «заглушки» стандартных обработчиков событий в модули и менеджеры объектов.

              \n

              3.5. Для минимизации ситуаций, когда в конфигурациях-потребителях возникает потребность в прямом обращении к объектам метаданным библиотеки (реквизитам, табличным частям справочников, документов и пр.), следует предусмотреть в библиотеке программный интерфейс, посредством которого прикладной код может взаимодействовать с библиотекой. Это снижает зависимость прикладного кода от особенностей реализации библиотеки и, тем самым, повышает его устойчивость к обновлениям на новые версии библиотеки.

              \n

              Например, вместо «прямого» запроса к библиотечному регистру из прикладного кода:

              \n

               Запрос = Новый Запрос;
               Запрос.Текст = \"ВЫБРАТЬ
                              | ОбластиДанных.Представление
                              |ИЗ
                              | РегистрСведений.ОбластиДанных КАК ОбластиДанных
                              |ГДЕ
                              | ОбластиДанных.ОбластьДанных = &ОбластьДанных\";
               Запрос.УстановитьПараметр(\"ОбластьДанных\", ПараметрыСеанса.ОбластьДанныхЗначение);
               ТаблицаОбластейДанных = Запрос.Выполнить().Выгрузить();
               ИмяПриложения = ?(ТаблицаОбластейДанных.Количество() = 0, \"\", ТаблицаОбластейДанных.Получить(0).Получить(0));

              \n

              следует предусмотреть в библиотеке экспортную функцию, которая специально предназначена для использования в прикладном коде:

              \n

              ИмяПриложения = РаботаВМоделиСервиса.ИмяПриложения();

              \n

              При этом если в текущей версии библиотеки отсутствует специализированная функция, а потребность обращаться к ее данным есть уже сейчас, то рекомендуется реализовать в прикладном коде временную функцию, которую при следующем обновлении библиотеки можно легко заменить на ее библиотечный эквивалент.

              \n

              3.6. Другой пример скрытия деталей реализации библиотеки от потребителя. Допустим:

              \n
                \n
              • в первой версии библиотеки потребителям предоставлялась экспортная функция общего модуля с повторным использованием возвращаемых значений; \n
              • но в следующей версии библиотеки это проектное решение пересмотрено в пользу «обычного» общего модуля, куда эта функция была перенесена (аналогично, если в обратную сторону).
              \n

              В данном примере, для того чтобы избавить потребителя библиотеки от дополнительных усилий по замене вызовов «старой» функции на новую, рекомендуется сразу размещать экспортную функцию в «обычном» модуле, в его разделе «программный интерфейс». Тогда эта функция, в зависимости от текущего проектного решения, может вызывать служебную функцию из модуля с повторным использованием возвращаемых значений или из любого другого модуля, или непосредственно сама содержать реализацию. Однако для потребителя ее местоположение уже не будет меняться в следующих версиях библиотеки.

              \n

              4. Для упрощения контроля изменений программного интерфейса в новых версиях библиотек рекомендуется воспользоваться приложенной обработкой.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "478", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: между \"Исключение\" и \"ОтменитьТранзакцию()\" есть исполняемый код.", +"Description": "

              Транзакции: правила использования

              #std783

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

              \n

              1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

              \n\n

              Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

              \n

              1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

              \n

              1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

              \n

              Правильно

              \n

              Процедура ЗаписатьДанныеВИБ()

              \n

                  НачатьТранзакцию();

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                      ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              Неправильно

              \n

              Процедура ЗаписатьДанныеВИБ()
               
                  НачатьТранзакцию();
                  ЗаписатьДокумент();

              \n

              КонецПроцедуры;

              \n

              Процедура ЗаписатьДокумент()

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                  ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

              \n
                \n
              • \n
                метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
                \n
              • \n
                все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
                \n
              • \n
                метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
                \n
              • \n
                необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
                \n
              • \n
                рекомендуется в блоке Исключение делать запись в журнал регистрации;
                \n
              • \n
                при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
              \n

              Пример

              \n

              НачатьТранзакцию();
              Попытка
                  БлокировкаДанных = Новый БлокировкаДанных;
                  ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
                  ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
                  ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
                  БлокировкаДанных.Заблокировать();

              \n

                  ... // чтение или запись данных

                  ДокументОбъект.Записать();

              \n

                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();

              \n

                  ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
                      УровеньЖурналаРегистрации.Ошибка,
                      ,
                      ,
                      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

              \n

                  ВызватьИсключение; // есть внешняя транзакция

              \n

              КонецПопытки;

              \n

              1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

              \n

              1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

              \n

              Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

              \n

              При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

              \n

              Правильно

              \n

              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
              Исключение
                  ... // действия по обработке исключения
              КонецПопытки;

              \n

              Неправильно

              \n

              НачатьТранзакцию();
              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();
              КонецПопытки;

              \n

              1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

              \n

              1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

              \n

              Пример

              \n

              Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

              \n

              1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

              \n

              2. Ограничение на длину транзакции.

              \n

              2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

              \n

              Пример

              \n

              При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

              \n

              2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

              \n

              2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

              \n

              2.2. Следует избегать транзакций, которые выполняются длительное время.

              \n

              Пример

              \n

              Неправильно

              \n

              Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

              \n

              Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

              \n

              Правильно

              \n

              Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

              \n

              См. также Особенности использования транзакций при обмене данными

              \n

              2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

              \n
                \n
              • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
              • блокировки, установленные в транзакции, остаются до конца транзакции; \n
              • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
              • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
              \n

              Все это в целом может снижать эффективность использования ресурсов.

              \n

              2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

              \n

              Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

              \n
                \n
              • \n
                возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
                \n
              • \n
                если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
                \n
              • \n
                так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
              \n

              2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

              \n
                \n
              • \n
                сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
                \n
              • \n
                если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
                \n
              • \n
                проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
                \n
              • \n
                запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
                \n
              • \n
                запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "482", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Запрос динамического списка, не содержащий секции \"ИЗ\", не переопределен в модуле формы.", +"Description": "

              Программное переопределение текстов запросов динамических списков

              \n

              1. Если текст запроса динамического списка переопределяется в коде, то рекомендуется придерживаться правил, описанных ниже. Это нужно для того, чтобы:

              \n
                \n
              • разработчики, глядя на запрос в динамическом списке, могли однозначно понять, что он переопределяется в коде конфигурации; \n
              • не снижать производительность при открытии формы, установке текста запроса, основной таблицы и признака динамического считывания данных.
              \n

              1.1. В редакторе запроса динамического списка следует устанавливать полноценный наиболее часто выполняемый текст запроса (запрос по умолчанию), чтобы при открытии формы, в большинстве случаев, не происходила программная установка текста запроса, снижающая производительность. Исключением является случай, когда текст запроса собирается программно.

              \n

              ПРАВИЛЬНО:

              \n

              Полноценный запрос:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              Запрос, требующий обязательной замены в коде конфигурации, т.к. не содержит секции ИЗ:

              \n

              ВЫБРАТЬ
                  ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) КАК Ссылка

              \n

              1.2. Псевдонимы таблиц должны заканчиваться постфиксом «Переопределяемый», чтобы визуально было заметно, что этот запрос может переопределяться в коде конфигурации.

              \n

              ПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  Номенклатура.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК Номенклатура

              \n

              1.3. Установка текста запроса и основной таблицы при первичной инициализации динамического списка (в ПриСозданииНаСервере) должна выполняться до любого обращения к настройкам этого списка (в т.ч. параметрам), чтобы не снижалась производительность. В остальных случаях, если требуется изменить текст запроса и основную таблицу, между этими действиями не следует обращаться к настройкам (можно до них или после). При наличии БСП, следует использовать процедуру ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(). Это необходимо для повышения производительности и возможности автоматического сбора переопределяемых текстов запросов динамических списков.

              \n

              ПРАВИЛЬНО:

              \n

              СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
              СвойстваСписка.ОсновнаяТаблица = \"Справочник.Номенклатура\";
              СвойстваСписка.ДинамическоеСчитываниеДанных = Истина;
              СвойстваСписка.ТекстЗапроса = ТекстЗапроса;
              ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список,
              СвойстваСписка);
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);

              \n

              НЕПРАВИЛЬНО:

              \n

              Список.ТекстЗапроса = ТекстЗапроса;
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);
              Список.ОсновнаяТаблица = ОсновнаяТаблица;

              \n

              В этом случае снижается производительность из-за того, что при изменении текста запроса или основной таблицы сбрасывается источник доступных настроек и при обращении к Список.Параметры источник инициализируется заново.

              \n

              2. Переопределяемые тексты запросов динамического списка можно размещать в любых модулях конфигурации, но следует следить за тем, чтобы текст запроса в динамическом списке был точно таким же, как и переопределяемый текст запроса по умолчанию (наиболее часто используемый).

              \n

              Этого можно добиться, например, если:

              \n
                \n
              • изменить текст запроса по умолчанию в коде конфигурации; \n
              • после изменения, скопировать текст запроса в динамический список; \n
              • или наоборот (изменить в динамическом списке, скопировать в код конфигурации).
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "483", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Псевдоним таблицы запроса динамического списка, переопределяемого программно, не заканчивается постфиксом \"Переопределяемый\".", +"Description": "

              Программное переопределение текстов запросов динамических списков

              \n

              1. Если текст запроса динамического списка переопределяется в коде, то рекомендуется придерживаться правил, описанных ниже. Это нужно для того, чтобы:

              \n
                \n
              • разработчики, глядя на запрос в динамическом списке, могли однозначно понять, что он переопределяется в коде конфигурации; \n
              • не снижать производительность при открытии формы, установке текста запроса, основной таблицы и признака динамического считывания данных.
              \n

              1.1. В редакторе запроса динамического списка следует устанавливать полноценный наиболее часто выполняемый текст запроса (запрос по умолчанию), чтобы при открытии формы, в большинстве случаев, не происходила программная установка текста запроса, снижающая производительность. Исключением является случай, когда текст запроса собирается программно.

              \n

              ПРАВИЛЬНО:

              \n

              Полноценный запрос:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              Запрос, требующий обязательной замены в коде конфигурации, т.к. не содержит секции ИЗ:

              \n

              ВЫБРАТЬ
                  ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) КАК Ссылка

              \n

              1.2. Псевдонимы таблиц должны заканчиваться постфиксом «Переопределяемый», чтобы визуально было заметно, что этот запрос может переопределяться в коде конфигурации.

              \n

              ПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  Номенклатура.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК Номенклатура

              \n

              1.3. Установка текста запроса и основной таблицы при первичной инициализации динамического списка (в ПриСозданииНаСервере) должна выполняться до любого обращения к настройкам этого списка (в т.ч. параметрам), чтобы не снижалась производительность. В остальных случаях, если требуется изменить текст запроса и основную таблицу, между этими действиями не следует обращаться к настройкам (можно до них или после). При наличии БСП, следует использовать процедуру ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(). Это необходимо для повышения производительности и возможности автоматического сбора переопределяемых текстов запросов динамических списков.

              \n

              ПРАВИЛЬНО:

              \n

              СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
              СвойстваСписка.ОсновнаяТаблица = \"Справочник.Номенклатура\";
              СвойстваСписка.ДинамическоеСчитываниеДанных = Истина;
              СвойстваСписка.ТекстЗапроса = ТекстЗапроса;
              ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список,
              СвойстваСписка);
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);

              \n

              НЕПРАВИЛЬНО:

              \n

              Список.ТекстЗапроса = ТекстЗапроса;
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);
              Список.ОсновнаяТаблица = ОсновнаяТаблица;

              \n

              В этом случае снижается производительность из-за того, что при изменении текста запроса или основной таблицы сбрасывается источник доступных настроек и при обращении к Список.Параметры источник инициализируется заново.

              \n

              2. Переопределяемые тексты запросов динамического списка можно размещать в любых модулях конфигурации, но следует следить за тем, чтобы текст запроса в динамическом списке был точно таким же, как и переопределяемый текст запроса по умолчанию (наиболее часто используемый).

              \n

              Этого можно добиться, например, если:

              \n
                \n
              • изменить текст запроса по умолчанию в коде конфигурации; \n
              • после изменения, скопировать текст запроса в динамический список; \n
              • или наоборот (изменить в динамическом списке, скопировать в код конфигурации).
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "484", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Программная установка свойств динамического списка выполняется без помощи процедуры \"ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка()\".", +"Description": "

              Программное переопределение текстов запросов динамических списков

              \n

              1. Если текст запроса динамического списка переопределяется в коде, то рекомендуется придерживаться правил, описанных ниже. Это нужно для того, чтобы:

              \n
                \n
              • разработчики, глядя на запрос в динамическом списке, могли однозначно понять, что он переопределяется в коде конфигурации; \n
              • не снижать производительность при открытии формы, установке текста запроса, основной таблицы и признака динамического считывания данных.
              \n

              1.1. В редакторе запроса динамического списка следует устанавливать полноценный наиболее часто выполняемый текст запроса (запрос по умолчанию), чтобы при открытии формы, в большинстве случаев, не происходила программная установка текста запроса, снижающая производительность. Исключением является случай, когда текст запроса собирается программно.

              \n

              ПРАВИЛЬНО:

              \n

              Полноценный запрос:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              Запрос, требующий обязательной замены в коде конфигурации, т.к. не содержит секции ИЗ:

              \n

              ВЫБРАТЬ
                  ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) КАК Ссылка

              \n

              1.2. Псевдонимы таблиц должны заканчиваться постфиксом «Переопределяемый», чтобы визуально было заметно, что этот запрос может переопределяться в коде конфигурации.

              \n

              ПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  НоменклатураПереопределяемый.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК НоменклатураПереопределяемый

              \n

              НЕПРАВИЛЬНО:

              \n

              ВЫБРАТЬ
                  Номенклатура.Ссылка КАК Ссылка
              ИЗ
                  Справочник.Номенклатура КАК Номенклатура

              \n

              1.3. Установка текста запроса и основной таблицы при первичной инициализации динамического списка (в ПриСозданииНаСервере) должна выполняться до любого обращения к настройкам этого списка (в т.ч. параметрам), чтобы не снижалась производительность. В остальных случаях, если требуется изменить текст запроса и основную таблицу, между этими действиями не следует обращаться к настройкам (можно до них или после). При наличии БСП, следует использовать процедуру ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(). Это необходимо для повышения производительности и возможности автоматического сбора переопределяемых текстов запросов динамических списков.

              \n

              ПРАВИЛЬНО:

              \n

              СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
              СвойстваСписка.ОсновнаяТаблица = \"Справочник.Номенклатура\";
              СвойстваСписка.ДинамическоеСчитываниеДанных = Истина;
              СвойстваСписка.ТекстЗапроса = ТекстЗапроса;
              ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список,
              СвойстваСписка);
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);

              \n

              НЕПРАВИЛЬНО:

              \n

              Список.ТекстЗапроса = ТекстЗапроса;
              Список.Параметры.УстановитьЗначениеПараметра(\"Параметр1\", 42);
              Список.ОсновнаяТаблица = ОсновнаяТаблица;

              \n

              В этом случае снижается производительность из-за того, что при изменении текста запроса или основной таблицы сбрасывается источник доступных настроек и при обращении к Список.Параметры источник инициализируется заново.

              \n

              2. Переопределяемые тексты запросов динамического списка можно размещать в любых модулях конфигурации, но следует следить за тем, чтобы текст запроса в динамическом списке был точно таким же, как и переопределяемый текст запроса по умолчанию (наиболее часто используемый).

              \n

              Этого можно добиться, например, если:

              \n
                \n
              • изменить текст запроса по умолчанию в коде конфигурации; \n
              • после изменения, скопировать текст запроса в динамический список; \n
              • или наоборот (изменить в динамическом списке, скопировать в код конфигурации).
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "486", +"Type": "VULNERABILITY", +"Severity": "CRITICAL", +"Name": "Отсутствует включение безопасного режима перед вызовом метода \"Выполнить\" или \"Вычислить\".", +"Description": "

              Ограничения на использование Выполнить и Вычислить на сервере

              #std770

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При разработке решений следует учитывать, что опасно не только непосредственное выполнение кода, написанного в режиме Предприятие, но и те места, где методами Выполнить или Вычислить исполняется код, сконструированный на основе параметров, переданных в серверные функции и процедуры. Ограничение не распространяется на код, выполняемый на клиенте.

              \n

              Например, код написан следующим образом:

              \n
                \n
              • в клиентской функции в форме создается структура, в которую вставляется строка, написанная разработчиком конфигурации; \n
              • клиентская функция передает эту структуру в серверную функцию формы; \n
              • серверная функция формы вызывает серверную функцию общего модуля; \n
              • в серверной функции исполняется код из строки, вставленной в структуру.
              \n

              В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

              \n
                \n
              • злоумышленник создает структуру, в которую вставляет строку с вредоносным кодом; \n
              • злоумышленник вызывает клиентскую функцию формы и таким образом исполняет вредоносный код на сервере.
              \n

              Еще опаснее, если методы, в которых с помощью Выполнить или Вычислить исполняется код, принимаемый из параметров, будут располагаться в модулях с установленным признаком ВызовСервера.

              \n

              2. Для исключения описанных уязвимостей, нужно в серверных процедурах и функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима:

              \n

              УстановитьБезопасныйРежим(Истина);
              Выполнить Алгоритм;

              \n

              В режиме сервиса, включение безопасного режима должно учитывать разделение данных, т.е. приведенный выше пример необходимо доработать следующим образом:

              \n

              УстановитьБезопасныйРежим(Истина);

              Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
                  УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
              КонецЦикла;

              Выполнить Алгоритм;

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

              \n
                \n
              • ОбщегоНазначения.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • ОбщегоНазначения.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • ОбщегоНазначения.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • ОбщегоНазначения.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:

              \n
                \n
              • РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              3.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен предварительно пройти аудит и должен быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

              \n
                \n
              • внешний код рекомендуется поместить во внешнюю обработку или отчет (в крайнем случае, допустимо передать его, как фрагмент текста); \n
              • передать внешний код администратору с пометкой, что необходимо выполнение кода в небезопасном режиме; \n
              • администратор или сотрудник с соответствующей квалификацией должен выполнить аудит полученного кода; \n
              • если код безопасен и надежен, администратор поместит внешний код в специальный справочник, доступ на запись в который есть только у него; \n
              • вместо Выполнить или Вычислить следует (или): \n
                  \n
                • подключить проверенную обработку из справочника и вызвать необходимый экспортный метод; \n
                • вызвать фрагмент кода с помощью специальной процедуры или функции, которая централизованно в конфигурации выполняет внешний код.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться подсистемой Дополнительные отчеты и обработки.

              \n

              4. Если конфигурация рассчитана на работу в модели сервиса, и в конфигурации предусмотрен перенос данных в сервис из локальной версии программы, необходимо обеспечить отключение всех пользовательских фрагментов кода или текстов запросов, которые были введены в локальной версии.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, также имеется возможность предварительной обработки данных, загружаемых из локальной версии в сервис (см. документацию к подсистеме Работа в модели сервиса).

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "487", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обнаружен вызов метода \"Выполнить\" вместо \"ОбщегоНазначения.ВыполнитьВБезопасномРежиме()\".", +"Description": "

              Ограничения на использование Выполнить и Вычислить на сервере

              #std770

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При разработке решений следует учитывать, что опасно не только непосредственное выполнение кода, написанного в режиме Предприятие, но и те места, где методами Выполнить или Вычислить исполняется код, сконструированный на основе параметров, переданных в серверные функции и процедуры. Ограничение не распространяется на код, выполняемый на клиенте.

              \n

              Например, код написан следующим образом:

              \n
                \n
              • в клиентской функции в форме создается структура, в которую вставляется строка, написанная разработчиком конфигурации; \n
              • клиентская функция передает эту структуру в серверную функцию формы; \n
              • серверная функция формы вызывает серверную функцию общего модуля; \n
              • в серверной функции исполняется код из строки, вставленной в структуру.
              \n

              В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

              \n
                \n
              • злоумышленник создает структуру, в которую вставляет строку с вредоносным кодом; \n
              • злоумышленник вызывает клиентскую функцию формы и таким образом исполняет вредоносный код на сервере.
              \n

              Еще опаснее, если методы, в которых с помощью Выполнить или Вычислить исполняется код, принимаемый из параметров, будут располагаться в модулях с установленным признаком ВызовСервера.

              \n

              2. Для исключения описанных уязвимостей, нужно в серверных процедурах и функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима:

              \n

              УстановитьБезопасныйРежим(Истина);
              Выполнить Алгоритм;

              \n

              В режиме сервиса, включение безопасного режима должно учитывать разделение данных, т.е. приведенный выше пример необходимо доработать следующим образом:

              \n

              УстановитьБезопасныйРежим(Истина);

              Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
                  УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
              КонецЦикла;

              Выполнить Алгоритм;

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

              \n
                \n
              • ОбщегоНазначения.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • ОбщегоНазначения.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • ОбщегоНазначения.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • ОбщегоНазначения.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:

              \n
                \n
              • РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              3.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен предварительно пройти аудит и должен быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

              \n
                \n
              • внешний код рекомендуется поместить во внешнюю обработку или отчет (в крайнем случае, допустимо передать его, как фрагмент текста); \n
              • передать внешний код администратору с пометкой, что необходимо выполнение кода в небезопасном режиме; \n
              • администратор или сотрудник с соответствующей квалификацией должен выполнить аудит полученного кода; \n
              • если код безопасен и надежен, администратор поместит внешний код в специальный справочник, доступ на запись в который есть только у него; \n
              • вместо Выполнить или Вычислить следует (или): \n
                  \n
                • подключить проверенную обработку из справочника и вызвать необходимый экспортный метод; \n
                • вызвать фрагмент кода с помощью специальной процедуры или функции, которая централизованно в конфигурации выполняет внешний код.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться подсистемой Дополнительные отчеты и обработки.

              \n

              4. Если конфигурация рассчитана на работу в модели сервиса, и в конфигурации предусмотрен перенос данных в сервис из локальной версии программы, необходимо обеспечить отключение всех пользовательских фрагментов кода или текстов запросов, которые были введены в локальной версии.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, также имеется возможность предварительной обработки данных, загружаемых из локальной версии в сервис (см. документацию к подсистеме Работа в модели сервиса).

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "488", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Обнаружен вызов метода \"Вычислить\" вместо \"ОбщегоНазначения.ВычислитьВБезопасномРежиме()\".", +"Description": "

              Ограничения на использование Выполнить и Вычислить на сервере

              #std770

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При разработке решений следует учитывать, что опасно не только непосредственное выполнение кода, написанного в режиме Предприятие, но и те места, где методами Выполнить или Вычислить исполняется код, сконструированный на основе параметров, переданных в серверные функции и процедуры. Ограничение не распространяется на код, выполняемый на клиенте.

              \n

              Например, код написан следующим образом:

              \n
                \n
              • в клиентской функции в форме создается структура, в которую вставляется строка, написанная разработчиком конфигурации; \n
              • клиентская функция передает эту структуру в серверную функцию формы; \n
              • серверная функция формы вызывает серверную функцию общего модуля; \n
              • в серверной функции исполняется код из строки, вставленной в структуру.
              \n

              В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

              \n
                \n
              • злоумышленник создает структуру, в которую вставляет строку с вредоносным кодом; \n
              • злоумышленник вызывает клиентскую функцию формы и таким образом исполняет вредоносный код на сервере.
              \n

              Еще опаснее, если методы, в которых с помощью Выполнить или Вычислить исполняется код, принимаемый из параметров, будут располагаться в модулях с установленным признаком ВызовСервера.

              \n

              2. Для исключения описанных уязвимостей, нужно в серверных процедурах и функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима:

              \n

              УстановитьБезопасныйРежим(Истина);
              Выполнить Алгоритм;

              \n

              В режиме сервиса, включение безопасного режима должно учитывать разделение данных, т.е. приведенный выше пример необходимо доработать следующим образом:

              \n

              УстановитьБезопасныйРежим(Истина);

              Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
                  УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
              КонецЦикла;

              Выполнить Алгоритм;

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

              \n
                \n
              • ОбщегоНазначения.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • ОбщегоНазначения.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • ОбщегоНазначения.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • ОбщегоНазначения.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:

              \n
                \n
              • РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              3.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен предварительно пройти аудит и должен быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

              \n
                \n
              • внешний код рекомендуется поместить во внешнюю обработку или отчет (в крайнем случае, допустимо передать его, как фрагмент текста); \n
              • передать внешний код администратору с пометкой, что необходимо выполнение кода в небезопасном режиме; \n
              • администратор или сотрудник с соответствующей квалификацией должен выполнить аудит полученного кода; \n
              • если код безопасен и надежен, администратор поместит внешний код в специальный справочник, доступ на запись в который есть только у него; \n
              • вместо Выполнить или Вычислить следует (или): \n
                  \n
                • подключить проверенную обработку из справочника и вызвать необходимый экспортный метод; \n
                • вызвать фрагмент кода с помощью специальной процедуры или функции, которая централизованно в конфигурации выполняет внешний код.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться подсистемой Дополнительные отчеты и обработки.

              \n

              4. Если конфигурация рассчитана на работу в модели сервиса, и в конфигурации предусмотрен перенос данных в сервис из локальной версии программы, необходимо обеспечить отключение всех пользовательских фрагментов кода или текстов запросов, которые были введены в локальной версии.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, также имеется возможность предварительной обработки данных, загружаемых из локальной версии в сервис (см. документацию к подсистеме Работа в модели сервиса).

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "489", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Обнаружен вызов метода \"Выполнить\" вместо \"РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме()\".", +"Description": "

              Ограничения на использование Выполнить и Вычислить на сервере

              #std770

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При разработке решений следует учитывать, что опасно не только непосредственное выполнение кода, написанного в режиме Предприятие, но и те места, где методами Выполнить или Вычислить исполняется код, сконструированный на основе параметров, переданных в серверные функции и процедуры. Ограничение не распространяется на код, выполняемый на клиенте.

              \n

              Например, код написан следующим образом:

              \n
                \n
              • в клиентской функции в форме создается структура, в которую вставляется строка, написанная разработчиком конфигурации; \n
              • клиентская функция передает эту структуру в серверную функцию формы; \n
              • серверная функция формы вызывает серверную функцию общего модуля; \n
              • в серверной функции исполняется код из строки, вставленной в структуру.
              \n

              В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

              \n
                \n
              • злоумышленник создает структуру, в которую вставляет строку с вредоносным кодом; \n
              • злоумышленник вызывает клиентскую функцию формы и таким образом исполняет вредоносный код на сервере.
              \n

              Еще опаснее, если методы, в которых с помощью Выполнить или Вычислить исполняется код, принимаемый из параметров, будут располагаться в модулях с установленным признаком ВызовСервера.

              \n

              2. Для исключения описанных уязвимостей, нужно в серверных процедурах и функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима:

              \n

              УстановитьБезопасныйРежим(Истина);
              Выполнить Алгоритм;

              \n

              В режиме сервиса, включение безопасного режима должно учитывать разделение данных, т.е. приведенный выше пример необходимо доработать следующим образом:

              \n

              УстановитьБезопасныйРежим(Истина);

              Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
                  УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
              КонецЦикла;

              Выполнить Алгоритм;

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

              \n
                \n
              • ОбщегоНазначения.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • ОбщегоНазначения.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • ОбщегоНазначения.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • ОбщегоНазначения.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:

              \n
                \n
              • РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              3.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен предварительно пройти аудит и должен быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

              \n
                \n
              • внешний код рекомендуется поместить во внешнюю обработку или отчет (в крайнем случае, допустимо передать его, как фрагмент текста); \n
              • передать внешний код администратору с пометкой, что необходимо выполнение кода в небезопасном режиме; \n
              • администратор или сотрудник с соответствующей квалификацией должен выполнить аудит полученного кода; \n
              • если код безопасен и надежен, администратор поместит внешний код в специальный справочник, доступ на запись в который есть только у него; \n
              • вместо Выполнить или Вычислить следует (или): \n
                  \n
                • подключить проверенную обработку из справочника и вызвать необходимый экспортный метод; \n
                • вызвать фрагмент кода с помощью специальной процедуры или функции, которая централизованно в конфигурации выполняет внешний код.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться подсистемой Дополнительные отчеты и обработки.

              \n

              4. Если конфигурация рассчитана на работу в модели сервиса, и в конфигурации предусмотрен перенос данных в сервис из локальной версии программы, необходимо обеспечить отключение всех пользовательских фрагментов кода или текстов запросов, которые были введены в локальной версии.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, также имеется возможность предварительной обработки данных, загружаемых из локальной версии в сервис (см. документацию к подсистеме Работа в модели сервиса).

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "490", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Обнаружен вызов метода \"Вычислить\" вместо \"РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме()\".", +"Description": "

              Ограничения на использование Выполнить и Вычислить на сервере

              #std770

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При разработке решений следует учитывать, что опасно не только непосредственное выполнение кода, написанного в режиме Предприятие, но и те места, где методами Выполнить или Вычислить исполняется код, сконструированный на основе параметров, переданных в серверные функции и процедуры. Ограничение не распространяется на код, выполняемый на клиенте.

              \n

              Например, код написан следующим образом:

              \n
                \n
              • в клиентской функции в форме создается структура, в которую вставляется строка, написанная разработчиком конфигурации; \n
              • клиентская функция передает эту структуру в серверную функцию формы; \n
              • серверная функция формы вызывает серверную функцию общего модуля; \n
              • в серверной функции исполняется код из строки, вставленной в структуру.
              \n

              В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

              \n
                \n
              • злоумышленник создает структуру, в которую вставляет строку с вредоносным кодом; \n
              • злоумышленник вызывает клиентскую функцию формы и таким образом исполняет вредоносный код на сервере.
              \n

              Еще опаснее, если методы, в которых с помощью Выполнить или Вычислить исполняется код, принимаемый из параметров, будут располагаться в модулях с установленным признаком ВызовСервера.

              \n

              2. Для исключения описанных уязвимостей, нужно в серверных процедурах и функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима:

              \n

              УстановитьБезопасныйРежим(Истина);
              Выполнить Алгоритм;

              \n

              В режиме сервиса, включение безопасного режима должно учитывать разделение данных, т.е. приведенный выше пример необходимо доработать следующим образом:

              \n

              УстановитьБезопасныйРежим(Истина);

              Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
                  УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
              КонецЦикла;

              Выполнить Алгоритм;

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

              \n
                \n
              • ОбщегоНазначения.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • ОбщегоНазначения.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • ОбщегоНазначения.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • ОбщегоНазначения.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:

              \n
                \n
              • РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме() вместо Выполнить; \n
              • РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме() вместо Вычислить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации() вместо формирования строки вызова метода модуля и передачи ее в Выполнить; \n
              • РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта() вместо формирования строки вызова метода объекта и передачи ее в Выполнить.
              \n

              3.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен предварительно пройти аудит и должен быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

              \n
                \n
              • внешний код рекомендуется поместить во внешнюю обработку или отчет (в крайнем случае, допустимо передать его, как фрагмент текста); \n
              • передать внешний код администратору с пометкой, что необходимо выполнение кода в небезопасном режиме; \n
              • администратор или сотрудник с соответствующей квалификацией должен выполнить аудит полученного кода; \n
              • если код безопасен и надежен, администратор поместит внешний код в специальный справочник, доступ на запись в который есть только у него; \n
              • вместо Выполнить или Вычислить следует (или): \n
                  \n
                • подключить проверенную обработку из справочника и вызвать необходимый экспортный метод; \n
                • вызвать фрагмент кода с помощью специальной процедуры или функции, которая централизованно в конфигурации выполняет внешний код.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться подсистемой Дополнительные отчеты и обработки.

              \n

              4. Если конфигурация рассчитана на работу в модели сервиса, и в конфигурации предусмотрен перенос данных в сервис из локальной версии программы, необходимо обеспечить отключение всех пользовательских фрагментов кода или текстов запросов, которые были введены в локальной версии.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем, также имеется возможность предварительной обработки данных, загружаемых из локальной версии в сервис (см. документацию к подсистеме Работа в модели сервиса).

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "491", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Некорректная локализация фрагмента текста запроса.", +"Description": "

              Запросы, динамические списки и отчеты на СКД: требования по локализации

              #std762

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В некоторых случаях строковые литералы из текстов запросов также могут оказаться частью пользовательского интерфейса. В таких случаях строковые литералы необходимо выносить из текста запроса в параметры.

              \n

              Неправильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА \"\"выпущена\"\" \n  | ИНАЧЕ \"\"в разработке\"\" \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\");
              \n

              Также неправильно:

              ТекстЗапроса = \n  \"ВЫБРАТЬ\n  |Версии.Ссылка,\n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА\n  | ТОГДА &ТекстВыпущеннойВерсии\n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии\n  |КОНЕЦ КАК ТекстПояснения\n  | ИЗ\n  | Справочник.Версии КАК Версии\");\n  \n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\"));\n  ТекстЗапроса = СтрЗаменить(ТекстЗапроса, \"&ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              Правильно:

              ЗапросПоВерсиям = Новый Запрос(\" \n  |ВЫБРАТЬ \n  |Версии.Ссылка, \n  |ВЫБОР КОГДА Версии.Выпущена = ИСТИНА \n  | ТОГДА &ТекстВыпущеннойВерсии \n  | ИНАЧЕ &ТекстНеВыпущеннойВерсии \n  |КОНЕЦ КАК ТекстПояснения \n  | ИЗ \n  | Справочник.Версии КАК Версии\"); \n\nЗапросПоВерсиям.УстановитьПараметр(\"ТекстВыпущеннойВерсии\", НСтр(\"ru='выпущена'\")); \nЗапросПоВерсиям.УстановитьПараметр(\"ТекстНеВыпущеннойВерсии\", НСтр(\"ru='в разработке'\"));
              \n

              2. Аналогичные требования предъявляются к выражениям СКД и запросам, которые используются в наборах данных СКД и содержат строковые литералы, выводимые в пользовательском интерфейсе. Например, если в выражении для параметров СКД встречаются строковые константы, требующие перевода, то следует:

              \n

              а) в запросе указывать строковые константы, соответствующие \"Правилам образования имен переменных\" (\"\"ЗавершитеСозданиеДокументов\" КАК Рекомендация \"), а в списке доступных значений поля указать локализуемый строковый литерал (\"Завершите создание документов\");

              \n

              б) либо значение таких параметров с помощью функции НСтр устанавливать не в колонке Выражение, а в модуле отчета в обработчике события ПриКомпоновкеРезультата

              \n

              Неправильно:

              ВЫБОР\n  КОГДА ВидОперации = \"Отгрузка клиентам\" ТОГДА 1\n  КОГДА ВидОперации = \"Возвраты товаров от клиентов\" ТОГДА 2\n  КОГДА ВидОперации = \"Приемка от поставщиков\" ТОГДА 3\nКОНЕЦ
              \n

              Правильно:

              ВЫБОР\n  КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1\n  КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2\n  КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3\nКОНЕЦ
              \n

              в) В выражениях, используемых в настройках СКД, например Выражение представления и Выражение упорядочивания на закладке Наборы данных, а также в других им подобных, необходимо использовать функцию НСтр, аналогично тому, как это делается в коде модулей (см. стандарт Интерфейсные тексты в коде: требования по локализации).

              \n

              Неправильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда \"<Для всех разделов и объектов, кроме указанных>\" \n    Иначе \"<Для всех объектов, кроме указанных>\" \n  Конец \n  Иначе Объект \nКонец\n
              \n

              Правильно:

              Выбор Когда Объект = Раздел \n  Тогда Выбор \n    Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка) \n      Тогда НСтр(\"ru='<Для всех разделов и объектов, кроме указанных>'\")\n    Иначе НСтр(\"ru='<Для всех объектов, кроме указанных>'\")\n  Конец \n  Иначе Объект \nКонец\n
              \n

              3. Для колонок отчета на СКД для поля выборки, полученного вычислением с заданием ему псевдонима, необходимо задавать синоним при разработке. Нельзя опираться на автоматически сгенерированный заголовок по имени/псевдониму.

              \n

              Неправильно:

              \n

              Правильно:

              \n

              В отчётах, если не стоит галочка у поля выборки, полученного вычислением с заданием ему псевдонима, оно не попадает в результаты поиска редактирования текстов интерфейсов.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "492", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неверно задан именованный параметр подстановки.", +"Description": "

              Интерфейсные тексты в коде: требования по локализации

              #std761

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Если в модулях конфигурации встречаются строки, предназначенные для пользовательского интерфейса (сообщения пользователю, надписи в формах, названия и подсказки команд, выражения в настройках СКД и т.п.) необходимо обеспечить возможность локализации таких строк.

              \n

              Для этого необходимо применять функцию НСтр вместо прямого использования строковых литералов. Иное использование строк, предназначенных для пользовательского интерфейса, не допускается.

              \n

              Например, неправильно:

              ПоказатьПредупреждение(, \"Для выполнения операции необходимо установить расширение работы с файлами.\");
              \n

              Правильно:

              ПоказатьПредупреждение(, НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));
              \n

              Также следует обращать внимание на корректное использование функции НСтр.

              \n

              Например, неправильно:

              ТекстСообщения = \"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\";\nПоказатьПредупреждение(, НСтр(ТекстСообщения));\n
              \n

              Правильно:

              ТекстСообщения = НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\");\nПоказатьПредупреждение(, ТекстСообщения);
              \n

              2. В том случае если строка является составной и включает в себя части, зависящие от тех или иных условий, тем не менее, следует использовать логически завершенные, целостные фразы (предложения). Необходимо применять функцию СтрШаблон (или аналогичную)  для подстановки параметров в строки сообщений пользователю.

              \n

              Это требование обусловлено, во-первых, разным расположением параметров в тексте предложения на различных языках, что приводит к необходимости изменения исходного кода для перестановки складываемых фрагментов строк, а во-вторых, невозможностью корректно  перевести отдельные несогласованные части предложения (наличие или отсутствие артиклей, предлогов, разное расположение знаков препинания в тексте предложения на различных языках и т.п.).

              \n

              Неправильно:

              СообщениеОНехватке = \"Не хватает товара \" + НаименованиеТовара + \" на складе \" + НаименованиеСклада + \".\";\n
              \n

              Правильно:

              ТекстСообщения = НСтр(\"ru = 'Не хватает товара %1 на складе %2.'\");
              СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);\n
              \n

              Также с помощью параметров подстановки не следует разрывать целостную фразу на отдельные логически незавершенные части. Вместо этого следует задавать в коде несколько строк со всеми вариантами фразы.

              \n

              Неправильно:

              НСтр(\"ru = '%1 пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\") // где параметр %1 может принимать слова \"Включить\", \"Копировать\" или \"Удалить\".\n
              \n

              Правильно:

              НСтр(\"ru = 'Включить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
              НСтр(\"ru = 'Копировать пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")
              НСтр(\"ru = 'Удалить пользователя \"\"%2\"\" в группу \"\"%3\"\"?'\")\n
              \n

              В то же время допустимым является:

              \n
                \n
              1. Составление текста из нескольких предложений (каждое из которых заключено в НСтр и переводится отдельно). \n
              2. Предложения, заканчивающиеся двоеточием. Например, НСтр(\"ru = 'Создание каталога не выполнено по причине:'\").
              \n

              В связи со сложившейся практикой, допускается использовать именованные параметры подстановки (параметры, включающие имя аналогично переменной, а не номер) только в двух вариантах: [Параметр], %Параметр%. Здесь Параметр должен удовлетворять требованиям стандарта Правила образования имен переменных.

              \n

              Правильно:

              СообщениеОНехватке = НСтр(\"ru='Не хватает товара %Товар% на складе %Склад%.'\") \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Товар%\", НаименованиеТовара); \nСообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, \"%Склад%\", НаименованиеСклада);\n
              \n

              3. При использовании в конфигурации Библиотеки стандартных подсистем для составных форматированных строк вместо объекта ФорматированнаяСтрока следует применять функцию ФорматированнаяСтрока общих модулей СтроковыеФункции или СтроковыеФункцииКлиент.

              \n

              Неправильно:

              Текст = Новый Массив; \nТекст.Добавить(НСтр(\"ru = 'Перед удалением расширения рекомендуется'\")); \nТекст.Добавить(\" \"); \nТекст.Добавить(Новый ФорматированнаяСтрока(НСтр(\"ru = 'выполнить резервное копирование информационной базы.'\"), ШрифтыСтиля.ПолужирныйШрифт); \nТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);\n
              \n

              Правильно:

              \n

              ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(\"ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'\");

              \n

              4. В функции НСтр строка ограничивается символами одинарных кавычек. Такое требование обусловлено частым использованием двойных кавычек в строковых литералах, а также встроенным в платформу механизмом редактирования строк на разных языках.

              \n

              Неправильно:

              ПоказатьПредупреждение(, НСтр(\"ru=Переменная типа \"\"Строка\"\"\")); \nПоказатьПредупреждение(, НСтр(\"ru=\"\"Переменная типа \"\"Строка\"\"\"\"\"));\n
              \n

              Правильно:

              ПоказатьПредупреждение(, НСтр(\"ru='Переменная типа \"\"Строка\"\"'\"));
              \n

              5. При использовании функций ЧислоПрописью, ПредставлениеПериода, СтрокаСЧислом не следует указывать параметр \"Л=\"(\"L=\") в строке форматирования. \n

              Неправильно:

              СуммаПрописью = ЧислоПрописью(2341.56, \"Л = ru_RU; ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

              Правильно:

              СуммаПрописью = ЧислоПрописью(2341.56, \"ДП = Истина\", НСтр(\"ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'\")); \n

              6. В редких случаях, например, когда нужно собрать длинное сообщение с предоставлением лога действий пользователя, допускается применять не замену строк в строке-шаблоне, а сложение строк. При этом неязыковые символы (чаще перенос строки) в начале и конце строк необходимо выделять в отдельные строковые литералы (которые пропускаются при переводе).

              \n

              Неправильно:

              ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:\n  |'\")\n  + ИнформацияОбОшибке;\n
              \n

              Правильно:

              ТекстСообщения = НСтр(\"ru = 'Не удалось сохранить файл документа по причине:'\")\n  + Символы.ПС + ИнформацияОбОшибке;\n
              \n

              В противном случае, при переводе строки на другой язык концевой пробел легко может быть не замечен переводчиком, так как переводчик не видит всего контекста, а только сводную таблицу строк, подлежащих переводу. Кроме того, может быть искажена при переводе фраза, так как её продолжение переводчику не видно и нет символа шаблона подстановки, поясняющего, что дальше будет продолжение.

              \n

              7. При вызове метода ПоказатьВопрос с указанием кнопок диалога в параметре Кнопки:
              • следует по возможности использовать системное перечисление КодВозвратаДиалога;
              • Если в перечислении нет нужной кнопки, вместе со значением, связанным с кнопкой, следует задавать его представление с использованием функции НСтр.

              \n

              Например, неправильно:

              Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\");\nКнопки.Добавить(\"Нет\");\nПоказатьВопрос(..., Кнопки);\n
              \n

              Правильно:

              Кнопки = Новый СписокЗначений;\nКнопки.Добавить(\"Отключить\", НСтр(\"ru='Отключить'\"));\nКнопки.Добавить(КодВозвратаДиалога.Нет);\nПоказатьВопрос(..., Кнопки);\n
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "494", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использование запроса, выполняющего соединение с вложенным запросом.", +"Description": "

              Ограничения на соединения с вложенными запросами и виртуальными таблицами

              #std655

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. При написании запросов не следует использовать соединения с вложенными запросами. Следует соединять друг с другом только объекты метаданных или временные таблицы. Если запрос использует соединения с вложенными запросами, то его следует переписать с использованием временных таблиц (не важно с какой стороны соединения находится вложенный запрос), кроме случая, когда вложенный запрос сканирует мало записей. 

              \n

              Если запрос содержит соединения с вложенными запросами, то это может привести к следующим негативным последствиям:

              \n
                \n
              • Крайне медленное выполнение запроса при слабой загрузке серверного оборудования. Замедление запроса может быть очень значительным (до нескольких порядков); \n
              • Нестабильная работа запроса. При некоторых условиях запрос может работать достаточно быстро, при других - очень медленно; \n
              • Значительная разница по времени выполнения запроса на разных СУБД; \n
              • Повышенная чувствительность запроса к актуальности и полноте статистик. Сразу после полного обновления статистик запрос может работать быстро, но через некоторое время опять замедлиться.
              \n

              Пример потенциально опасного запроса, использующего соединение с вложенным запросом:

              \n

              ВЫБРАТЬ ...
              ИЗ Документ.РеализацияТоваровУслуг
              ЛЕВОЕ СОЕДИНЕНИЕ (
                 ВЫБРАТЬ ИЗ РегистрСведений.Лимиты
                 ГДЕ ...
                 СГРУППИРОВАТЬ ПО ...
              ) ПО ...

              \n

              Оптимизатор сервера СУБД (независимо от того, какую СУБД вы используете) не всегда может правильно оптимизировать подобный запрос. В данном случае, проблемой для оптимизатора является выбор правильного способа соединения. Существуют несколько алгоритмов соединения двух выборок. Выбор того или иного алгоритма зависит от того, сколько записей будет содержаться в одной и в другой выборке. В том случае, если вы соединяете две физические таблицы, СУБД может легко определить объем обоих выборок на основании имеющейся статистики. Если же одна из соединяемых выборок представляет собой вложенный запрос, то понять, какое количество записей она вернет, становится очень сложно. В этом случае СУБД может ошибиться с выбором плана, что приведет к катастрофическому падению производительности запроса.

              \n

              1.2. Для вышеприведенного примера получится следующий пакетный запрос:

              \n

              // Создать менеджер временных таблиц
              МенеджерВТ = Новый МенеджерВременныхТаблиц;
              Запрос = Новый Запрос;
              Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
              // Текст пакетного запроса
              Запрос.Текст = \"
                // Заполняем временную таблицу. Запрос к регистру лимитов.
                 | ВЫБРАТЬ ...
                 | ПОМЕСТИТЬ Лимиты
                 | ИЗ РегистрСведений.Лимиты
                 | ГДЕ ...
                 | СГРУППИРОВАТЬ ПО ...
                 | ИНДЕКСИРОВАТЬ ПО ...;
               
                // Выполняем основной запрос с использованием временной таблицы
                 ВЫБРАТЬ ...
                 ИЗ Документ.РеализацияТоваровУслуг
                 ЛЕВОЕ СОЕДИНЕНИЕ Лимиты
                 ПО ...;\"

              \n

              Переписывание запроса по приведенной выше методике имеет своей целью упростить работу оптимизатору СУБД. В переписанном запросе все выборки, участвующие в соединениях будут представлять собой физические таблицы, и СУБД сможет легко определить размер каждой выборки. Это позволит СУБД гарантированно выбрать самый быстрый из всех возможных планов. Причем, СУБД будет делать правильный выбор независимо ни от каких условий. Переписанный подобным образом запрос будет работать одинаково хорошо на любых СУБД, что особенно важно при разработке тиражных решений. Кроме того, переписанный подобным образом запрос лучше читается, проще для понимания и отладки. 

              \n

              2. Если в запросе используется соединение с виртуальной таблицей языка запросов 1С:Предприятия (например, РегистрНакопления.Товары.Остатки) и запрос работает с неудовлетворительной производительностью, то рекомендуется вынести обращение к виртуальной таблице в отдельный запрос с сохранением результатов во временной таблице (см. пункт 1.1).

              \n

              3. Следует избегать неявных подзапросов, которые получаются при использовании вложенных соединений:

              \n

              ВЫБРАТЬ ...
              ИЗ Справочник.Номенклатура
                  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах
                      ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций
                      ПО ...
                  ПО ...

              \n

              Проблема в том, что, по сути, этот запрос аналогичен следующему:

              \n

              ВЫБРАТЬ ...
              ИЗ Справочник.Номенклатура
                  ЛЕВОЕ СОЕДИНЕНИЕ (
                      ВЫБРАТЬ ...
                      ИЗ РегистрНакопления.ТоварыНаСкладах
                          ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций
                          ПО ...)
                  ПО ...

              \n

              Вместо вложенных соединений, как показано выше, следует использовать последовательные соединения:

              \n

              ВЫБРАТЬ ...
              ИЗ Справочник.Номенклатура
                  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах
                  ПО ...
                  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыОрганизаций
                  ПО ...

              \n

              При этом следует понимать, что вложенные и последовательные соединения – это разные запросы, которые могут дать разный результат.

              \n

              Если вложенное соединение использовано из предположения, что оно аналогично последовательному соединению, то следует просто переписать его на последовательное соединение.

              \n

              Если вложенное соединение делается осмысленно, то от него следует отказаться, т.к. оно может существенно снизить производительность, как и соединение с подзапросом. Как и в случае с подзапросом, такое соединение можно заменить на соединение с временной таблицей, но лучше вначале подумать, как заменить его на последовательное соединение, т.к. оно будет работать эффективнее временной таблицы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "495", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Вызов функции \"КаталогВременныхФайлов()\".", +"Description": "

              Доступ к файловой системе из кода конфигурации

              #std542

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При обращении из кода конфигурации к файлам и каталогам файловой системы следует иметь в виду, что доступ к ним ограничен правами пользователя операционной системы, от имени которого запущено приложение.

              \n

              1.1. Если доступ к файловой системе осуществляется из кода, выполняемого на клиенте, то он выполняется под правами пользователя, от имени которого запущено приложение (тонкий, толстый или веб-клиент). Как правило, это текущий пользователь операционной системы.

              \n

              1.2. Если доступ к файловой системе осуществляется из кода, выполняемого на сервере, то:

              \n
                \n
              • при использовании клиент-серверной информационной базы, доступ ограничен правами пользователя, от имени которого запущен сервер 1С:Предприятия (*); \n
              • при использовании файловой базы, опубликованной на веб-сервере, доступ ограничен правами пользователя, от имени которого запущен веб-сервер.
              \n

              * Рабочие процессы могут быть также запущены от имени другого пользователя, отличного от того, под которым запускается агент сервера. Подробнее см. руководство администратора клиент-серверного варианта, описание служебного файла swpuser.ini

              \n\n\n\n
              \n

                   Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              2. Запрещается выполнять запись каких-либо файлов в каталог исполняемых файлов 1С:Предприятия, получаемого с помощью метода КаталогПрограммы. Использование метода КаталогПрограммы допустимо только для чтения или запуска файлов. Например, при работе в ОС Windows, для запуска копии тонкого клиента 1С:Предприятия текущей версии, допустимо использовать:

              \n

              ЗапуститьПриложение(КаталогПрограммы() + \"1cv8s.exe\");

              \n

              3. Даже если не планируется локализация конфигурации на другие языки, следует обеспечивать переносимость файлов, сформированных из кода конфигурации, между различными операционными системами с различными кодировками. Для этого необходимо:

              \n

              3.1. В именах файлов, автоматически формируемых из кода конфигурации, указывать только английские буквы, а также цифры, а в качестве кодировки текстовых файлов использовать только UTF-8 (именно этот формат предпочтителен, т.к. только с ним корректно работает операционная система macOS).

              \n

              Это ограничение распространяется на файлы сообщений обмена, выгрузки данных, электронных документов и пр., которые автоматические формируются системой, в том числе на файлы, упакованные в архивы (например, zip). Исключение составляют случаи, когда на формат файлов невозможно повлиять, например, это формат сторонней системы.

              \n

              3.2. В тех случаях, когда имя файла не генерируется системой, а его явно вводит пользователь, разрешить ввод русскоязычных имен, но при этом дать возможность транслитерировать его в англоязычное имя. По умолчанию, если это технически возможно и не снижает удобство работы, рекомендуется предлагать англоязычное имя файла, а для текстовых файлов – сохранение в кодировке UTF-8. 

              \n

              Также эти рекомендации по выбору имени и кодировки файла следует разместить в справке к тем местам программы, где пользователь имеет возможность сохранять файлы и выбирать кодировку.

              \n

              В конфигурациях на базе Библиотеки стандартных подсистем для транслитерации имен файлов рекомендуется использовать функцию СтроковыеФункцииКлиентСервер.СтрокаЛатиницей.

              \n

              \n

              Работа с временными файлами и каталогами

              \n

              При необходимости использования временных файлов и каталогов необходимо соблюдать следующие требования:

              \n

              1. Для получения имени временного файла следует использовать метод ПолучитьИмяВременногоФайла (исключение составляет веб-клиент, см. ниже п. 3). В противном случае возможна некорректная работа конфигурации в многопользовательском режиме, с включенными профилями безопасностями, возникновение проблем с правами доступа к файлам операционной системы, а также неконтролируемое увеличение количества ненужных временных файлов, которые не будут своевременно удалены.

              \n

              Например, неправильно:

              \n

              ИмяПромежуточногоФайла = \"C:\\Временные файлы 1С\\TempFile.xml\";
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              У текущего пользователя может не быть прав на запись в указанный каталог. Кроме того, при одновременном выполнении этого кода из двух разных сеансов возникнет ошибка.

              \n

              Правильно:

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              При использовании этой функции будет получено уникальное имя, гарантирован доступ к файлу.

              \n

              Кроме того, при использовании метода ПолучитьИмяВременногоФайла платформа 1С:Предприятие сохраняет контроль над такими файлами и автоматически удаляет их при перезапуске рабочего процесса (если файл был создан на стороне сервера) или клиентского приложения (если файл был создан на стороне клиента).

              \n

              Если же имя временного файла было сформировано каким-то другим способом, и прикладной код не удалил (либо по какой-то причине не смог удалить) ранее созданный временный файл, то платформа такой файл не контролирует, и он остается в файловой системе на неопределенное время. Накапливание «потерянных» временных файлов может представлять серьезную проблему, особенно для информационных баз с большим количеством активно работающих пользователей (например, при работе в режиме сервиса).

              \n

              Таким образом, неправильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = Строка(Новый УникальныйИдентификатор) + \".xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              Если по каким-то причинам прикладной код не удалит созданный файл (например, между блоками создания и удаления временного файла возникнет штатное или нештатное исключение), этот файл так и останется в каталоге временных файлов.

              \n

              Правильно:

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              При использовании метода ПолучитьИмяВременногоФайла будет получено уникальное имя, гарантирован доступ к файлу, а также временный файл будет автоматически удален платформой 1С:Предприятие после завершения рабочего процесса сервера или клиентского приложения.

              \n

              2. Для создания временного каталога рекомендуется также использовать имя, полученное при помощи метода ПолучитьИмяВременногоФайла (исключение составляет веб-клиент, см. ниже п. 3). Это гарантирует уникальность имени создаваемого каталога при работе в многопользовательском режиме и гарантирует, что после перезапуска рабочего процесса или клиентского приложения временный каталог будет автоматически удален платформой 1С:Предприятие. После этого, внутри созданного каталога можно создавать другие каталоги и файлы без ограничений.

              \n

              3.1. При выполнении кода веб-клиентом метод ПолучитьИмяВременногоФайла недоступен. Поэтому для формирования имен временных файлов и каталогов необходимо использовать функцию КаталогВременныхФайлов и объект УникальныйИдентификатор.

              \n

              Неправильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = \"TempDataFile.xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              Правильно:

              \n

              Каталог = КаталогВременныхФайлов();
              ИмяФайла = Строка(Новый УникальныйИдентификатор) + \".xml\";
              ИмяПромежуточногоФайла = Каталог + ИмяФайла;
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              3.2. Если в конфигурацию встроена Библиотека стандартных подсистем, для создания временных каталогов на стороне клиента необходимо использовать процедуру ФайловаяСистемаКлиент.СоздатьВременныйКаталог.

              \n

              4. После окончания работы с временным файлом или каталогом, его необходимо удалить самостоятельно. Нельзя рассчитывать на автоматическое удаление файлов и каталогов при следующем запуске платформы, это может привести к исчерпанию свободного места в каталоге временных файлов.

              \n

              ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"xml\");
              Данные.Записать(ИмяПромежуточногоФайла);

              \n

              // Работа с файлом
              ...

              \n

              // Удаляем временный файл
              Попытка
                 УдалитьФайлы(ИмяПромежуточногоФайла);
              Исключение
                 ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Мой механизм.Действие'\"), УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
              КонецПопытки;

              \n
              \n

              См. также: Использование Журнала регистрации.

              \n

              5. При использовании временных файлов и каталогов на сервере, необходимо полностью завершать работу с ними в рамках одного серверного вызова. При работе конфигурации с использованием кластера серверов, при следующем вызове эти файлы могут стать недоступны, так как код начнет исполняться на другом компьютере. При необходимости сохранить данные между серверными вызовами в пределах одного сеанса следует использовать временное хранилище платформы (методы ПоместитьВоВременноеХранилище, ПолучитьИзВременногоХранилища).

              \n

              5.1. В редких случаях может возникнуть необходимость передачи данных во временных файлах между сеансами, например, при подготовке данных для фонового задания, при организации длительного процесса, обслуживающего несколько последовательных вызовов web-сервиса. Необходимо самостоятельно обеспечивать гарантировано общее место хранения, права для доступа к файлам из разных мест их обработки, удаление файлов по истечению сроков их обработки или аварийного завершения процесса обработки. Рекомендуется использовать следующий подход:

              \n
                \n
              • Для обеспечения доступа со всех возможных мест обработки заводится константа для хранения общего пути к файлам, доступного для доступа со всех серверов кластера; \n
              • При создании временных файлов их имена заносятся во вспомогательный регистр сведений с сохранением времени создания файла; \n
              • При штатном прохождении процесса, последняя операция, которой были нужны файлы, перед своим завершением удаляет как сам файл, так и записи о них во вспомогательном регистре; \n
              • Вспомогательное регламентное задание периодически проверяет наличие записей во вспомогательном регистре, время существования которых заведомо превышает время штатного завершения процесса. При обнаружении таких записей, задание удаляет временные файлы и записи о них.
              \n

              \n

              Передача файлов между клиентом и сервером

              \n

              1. При одновременной работе с файлом на клиенте и на сервере необходимо использовать передачу файла через временное хранилище (методы ПоместитьФайлы, ПолучитьФайл, ПолучитьФайлы, НачатьПомещениеФайла, ПоместитьВоВременноеХранилище, ПолучитьИзВременногоХранилища). В общем случае клиент и серверы кластера - это разные компьютеры с разной файловой системой, причем доступ к файлам может происходить под разными пользователями ОС с различными правами.

              \n

              Неправильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...
                 ИмяФайла = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 Результат = ПроизвестиОбработкуНаСервере(ИмяФайла);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаСервере
              Функция ПроизвестиОбработкуНаСервере(ИмяФайла) 

              \n

                 Чтение = Новый ЧтениеТекста(ИмяФайла);
                 ...

              \n

                 Результат = Чтение.Прочитать();
                 Возврат Результат;

              \n

              КонецФункции

              \n

              Правильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...

              \n

                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                  НачатьПомещениеФайла(ОписаниеОповещения,,
                         ИмяФайлаДляОбработки,  Ложь,
                         УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаСервере
              Функция ПроизвестиОбработкуНаСервере(Адрес)

              \n

                 Данные = ПолучитьИзВременногоХранилища(Адрес);
                 ИмяПромежуточногоФайла = ПолучитьИмяВременногоФайла(\"txt\");
                 Данные.Записать(ИмяПромежуточногоФайла);

              \n

                 Чтение = Новый ЧтениеТекста(ИмяПромежуточногоФайла);
                 ...
                 Результат = Чтение.Прочитать();
                 ...

              \n

                 УдалитьФайлы(ИмяПромежуточногоФайла);  

              \n

                 Возврат Результат;

              \n

              КонецФункции

              \n

              2. Для сохранения данных во временном хранилище между несколькими серверными вызовами, при помещении его в хранилище необходимо использовать параметр УникальныйИдентификаторФормы метода ПоместитьФайл, передав в него идентификатор текущей формы. Такие значения будут удалены из временного хранилища только при закрытии указанной формы. При этом, при повторном помещении того же файла во временное хранилище, предыдущее значение необходимо удалять вручную. Например:

              \n

              Неправильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()

              \n

                 ...
                 // Первый серверный вызов
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиНачальнуюОбработкуНаСервере(Адрес);
                 ПродолжитьОбработкуФайла();
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайла()

              \n

                 ...
                 // Второй серверный вызов с той же версией файла
                 Результат = ПроизвестиПромежуточнуюОбработкуНаСервере(Адрес);
                 ...

              \n

                 // Третий серверный вызов с новой версией файла
                 ОписаниеОповещения = Новый ОписаниеОповещения(
                 \"ПродолжитьОбработкуФайлаЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте

              \n

              Процедура ПродолжитьОбработкуФайлаЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиКонечнуюбОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              При этом во временном хранилище формы останется две копии файлов. Адрес второй копии будет находиться в переменной Адрес, а адрес первой копии будет утерян. Это приводит к затрате дополнительных ресурсов приложения, замедлению работы.

              \n

              Правильно:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()

              \n

                 ...
                 // Первый серверный вызов
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";  

              \n

                 ОписаниеОповещения = Новый ОписаниеОповещения(
                    \"ОбработатьФайлЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиНачальнуюОбработкуНаСервере(Адрес);
                 ПродолжитьОбработкуФайла();
                 ...

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайла()

              \n

                 ...
                 // Второй серверный вызов с той же версией файла
                 Результат = ПроизвестиПромежуточнуюОбработкуНаСервере(Адрес);
                 ...

              \n

                 // Третий серверный вызов с новой версией файла
                 УдалитьИзВременногоХранилища(Адрес);

              \n

                 ОписаниеОповещения = Новый ОписаниеОповещения(
                 \"ПродолжитьОбработкуФайлаЗавершение\", ЭтотОбъект);

              \n

                 НачатьПомещениеФайла(ОписаниеОповещения,,
                    ИмяФайлаДляОбработки, Ложь,
                    УникальныйИдентификатор);

              \n

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ПродолжитьОбработкуФайлаЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры)  

              \n

                 ...
                 Результат = ПроизвестиКонечнуюбОбработкуНаСервере(Адрес);
                 ...

              \n

              КонецПроцедуры

              \n

              3. Если в конфигурацию встроена Библиотека стандартных подсистем для помещения файлов во временное хранилище необходимо использовать процедуры ЗагрузитьФайл и ЗагрузитьФайлы общего модуля ФайловаяСистемаКлиент. Для сохранения данных файла между несколькими серверными вызовами необходимо использовать свойство ИдентификаторФормы параметра ПараметрыЗагрузки:

              \n

              &НаКлиенте
              Процедура ОбработатьФайл()
                 ...
                 ИмяФайлаДляОбработки = \"C:\\Файлы для обработки\\Загрузка.xml\";
                 ОписаниеОповещения = Новый ОписаниеОповещения(\"ОбработатьФайлЗавершение\", ЭтотОбъект);

                 ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
                 ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;
                 ПараметрыЗагрузки.Интерактивно = Ложь;

              \n

                 ФайловаяСистемаКлиент.ЗагрузитьФайл(ОписаниеОповещения,
                 ПараметрыЗагрузки, ИмяФайлаДляОбработки);

              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура ОбработатьФайлЗавершение(ПомещенныйФайл, ДополнительныеПараметры)

                 ...
                 Результат = ПроизвестиОбработкуНаСервере(Адрес);
                 ...

              КонецПроцедуры

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "496", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не заполнен параметр \"РегламентноеЗадание\" при вызове процедуры \"ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();\".", +"Description": "

              Общие требования к регламентным заданиям

              #std540

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В общем случае, регламентные задания следует использовать, когда необходимо выполнить определенные периодические или однократные действия в соответствии с расписанием.

              \n

              2. При этом если регламентные задания не требуется добавлять или удалять в зависимости от действий пользователя или логики конфигурации, следует использовать предопределенные регламентные задания. Такие задания автоматически создаются в информационной базе с тем расписанием и состоянием, которое было задано разработчиком в Конфигураторе. Примеры предопределенных регламентных заданий:

              \n
                \n
              • загрузка курсов валют; \n
              • извлечение текста для полнотекстового индексирования; \n
              • обновление агрегатов.
              \n

              3.1. Если выполнение регламентного задания зависит от включенных одной или нескольких функциональных опций (ФО), то необходимо программно управлять признаком предопределенного регламентного задания Использование в зависимости от установленных ФО. Иначе регламентное задание будет приводить к запуску сеанса, занимая вычислительные ресурсы сервера 1С:Предприятие.

              \n

              Например, имеем регламентное задание ПолучениеИОтправкаЭлектронныхПисем (с установленным флажком Использование), которое должно выполняться только в том случае, если установлена ФО ИспользоватьПочтовыйКлиент.

              \n

              Неправильно: создавать предопределенное регламентное задание, зависящее от ФО, с установленным флажком Использование.

              \n

              Правильно: снять флажок Использование и управлять использованием регламентного задания в зависимости от включения/выключения функциональной опции.
              Если в конфигурации используется подсистема «Регламентные задания» Библиотеки стандартых подсистем (БСП), то для такой настройки следует использовать процедуру ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

              \n

              Настройка = Настройки.Добавить();
              Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.ОбновлениеСтатусовДоставкиSMS;
              Настройка.ФункциональнаяОпция = Метаданные.ФункциональныеОпции.ИспользоватьПочтовыйКлиент;
              Настройка.ДоступноВМоделиСервиса = Ложь;

              \n

              После чего в состав определяемого типа МестоХраненияФункциональныхОпций необходимо добавить константы, соответствующие функциональным опциям, используемым для управления регламентными заданиями.

              \n

              Для конфигураций без БСП следует управлять использованием регламентного задания, разместив, например, в модуле менеджера значения константы ИспользоватьПочтовыйКлиент следующий код:

              \n

              Процедура ПриЗаписи(Отказ)
               
               Задание = РегламентныеЗадания.НайтиПредопределенное(Метаданные.РегламентныеЗадания.ПолучениеИОтправкаЭлектронныхПисем);
               
               Если Задание.Использование <> Значение Тогда
                Задание.Использование = Значение;
                Задание.Записать();
               КонецЕсли;
               
              КонецПроцедуры

              \n

              3.2. Дополнительно следует обезопасить выполнение регламентного задания, включенного через консоль или другим способом, минуя включение ФО, вставив в начало процедуры обработки регламентного задания следующий код:

              \n

              ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();
              Если НЕ ПолучитьФункциональнуюОпцию(\"ИспользоватьПочтовыйКлиент\") Тогда
               ВызватьИсключение НСтр(\"ru = 'Регламентное задание недоступно по функциональным опциям.'\");
              КонецЕсли;

              \n

              Если в конфигурации используется подсистема «Регламентные задания» БСП и настроены зависимости регламентных заданий от ФО (как указано в п.3.1), то вместо этого достаточно вставить вызов, как показано в п.6.

              \n

              4.1. Если выполнение регламентного задания зависит от данных информационной базы, то флажок Предопределенное у регламентного задания следует отключать.
              Например:

              \n
                \n
              • обмен данными с другими информационными базами должен проводиться с каждой базой по индивидуальному расписанию; \n
              • запуск каждой дополнительной обработки в базе требуется выполнять по отдельному расписанию.
              \n

              В этих случаях требуется создавать экземпляры регламентных заданий и параметризовать их объектами ИБ (например, узлами ИБ, элементами справочника Дополнительные обработки и т.п.) из кода на встроенном языке с помощью метода РегламентныеЗадания.СоздатьРегламентноеЗадание. При этом в свойстве Наименование необходимо указывать представление объекта, на основании которого создается регламентное задание. Например, есть рассылка отчетов (элемент справочника), расписание, которое было настроено в карточке рассылки и ее автор, тогда добавление на основании нее регламентного задания будет выглядеть так:

              \n

              // Снимаем ограничение, что только администратор может создавать регламентные задания.
              УстановитьПривилегированныйРежим(Истина);
              Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.РассылкаОтчетов);

              \n

              ПараметрыЗадания = Новый Массив;
              ПараметрыЗадания.Добавить(РассылкаОтчетов);
              Задание.Параметры = ПараметрыЗадания;

              \n

              Задание.ИмяПользователя = АвторРассылки;
              Задание.Использование = Истина;
              Задание.Наименование = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(\"ru = 'Рассылка отчетов: %1'\"), СокрЛП(РассылкаОтчетов);
              Задание.Расписание = РасписаниеРассылки; 
              Задание.Записать();

              \n

              4.2. Если в конфигурации используется подсистема «Регламентные задания» БСП, то необходимо также запрещать интерактивное создание и запуск параметризованных регламентных заданий из формы Регламентные и фоновые задания. Для этого необходимо указать такое задание в процедуре ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

              \n

              Настройка = Настройки.Добавить();
              Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.РассылкаОтчетов;
              Настройка.Параметризуется = Истина;

              \n

              Также выполнить п.6.

              \n

              5. Во избежание различных конфликтных ситуаций рекомендуется в копиях информационной базы автоматически блокировать все регламентные задания, обращающиеся к внешним ресурсам (рассылка почты, синхронизация данных с другими программами и т.п.). Например, если копия информационной базы была развернута для тестирования или передана в службу технической поддержки.

              \n

              Если в конфигурации используется подсистема «Регламентные задания» БСП, то для этого необходимо перечислить такие задания в процедуре ПриОпределенииНастроекРегламентныхЗаданий общего модуля РегламентныеЗаданияПереопределяемый. Например:

              \n

              Настройка = Настройки.Добавить();
              Настройка.РегламентноеЗадание = Метаданные.РегламентныеЗадания.РассылкаОтчетов;
              Настройка.РаботаетСВнешнимиРесурсами = Истина;

              \n

              И выполнить п.6. \n

              В этом случае при перемещении информационной базы администратору будет задан вопрос об отключении таких заданий. \n

              6. Если регламентное задание попадает под требования, описанные в пунктах 3.1, 4.2, 5 и используется подсистема «Регламентные задания» БСП, то вначале процедур обработчиков таких заданий необходимо помещать вызов: \n

              ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.<ИмяЗадания>); \n

              Первый параметр при этом заполнять обязательно. \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "497", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В имени макета отсутствует суффикс (например, \"_ru\").", +"Description": "

              Макеты: требования по локализации и поддержке разных языков интерфейса

              #std766

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Как правило, перевод табличных, текстовых и HTML-макетов на другие языки не требует каких-либо подготовительных действий при разработке конфигурации. Особым случаем являются двоичные макеты, подлежащие переводу, а также HTML-макеты, содержащие изображения, которые должны быть отдельно подготовлены на разных языках. Например, это двоичные макеты печатных форм в форматах офисных документов, HTML-макеты с инструкциями, включающие скриншоты интерфейса программы или изображения, содержащие текстовую информацию.

              \n

              Такой макет необходимо пометить специальным образом, пометка будет означать, что при переводе будет необходимо создавать копию, а не переводить содержимое макета. Для этого в имени макета следует указывать постфикс в виде подчеркивания и кода языка так, как он задан в метаданных, в языке Русский в свойстве Код языка: \"_ru\".
              Например, неправильно:

              \n

              макет ПФ_ODT_СчетНаОплату (макет печатной формы счета на оплату в формате OpenOffice Writer)

              \n

              правильно указывать в имени постфикс основного языка:

              \n

              макет ПФ_ODT_СчетНаОплату_ru

              \n

              При добавлении языков интерфейса следует добавлять макеты с соответствующими постфиксами. В коде, в зависимости от языка, использовать макет с соответствующим постфиксом. Например, неправильно:

              ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\");\n
              \n

              правильно:

              \n

              ... = ПолучитьОбщийМакет(\"ПФ_ODT_СчетНаОплату\" +  \"_\" + ТекущийЯзык());

              \n

              Кроме того, для исключения ошибок при частичном переводе конфигурации, рекомендуется выполнять получение макета в три этапа:

              \n
                \n
              • Сначала по ИмяМакета + \"_\" + ТекущийЯзык(); \n
              • Если не найден, то по ИмяМакета + \"_\" + Метаданные.ОсновнойЯзык.КодЯзыка; \n
              • Если не найден, то по переданному имени ИмяМакета. \n
              • И наконец установить свойство КодЯзыка (у табличного документа) или КодЯзыкаМакета (у текстового документа и HTML-макета), как указано далее в п.2.
              \n

              2. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может возникнуть задача в одном сеансе пользователя формировать печатные формы на разных языках, а не только на текущем языке интерфейса. Например, в сеансе англоязычного пользователя сформировать счет на оплату на русском языке.

              \n

              Для получения данных из табличного, текстового или HTML-макета на заданном языке, отличном от языка интерфейса текущего пользователя, необходимо использовать свойство КодЯзыка (доступно у табличного документа) и КодЯзыкаМакета (у текстового документа и HTML-макета).

              \n

              Правильно:

              Макет = ПолучитьОбщийМакет(\"ПечатнаяФорма\");\nМакет.КодЯзыкаМакета = \"ru\";\nHTMLДокумент = Макет.ПолучитьДокументHTML();\n
              \n

              3. При разработке конфигураций, рассчитанных на несколько языков интерфейса, может также возникнуть задача формировать печатные формы строго на одном языке, не зависимо от текущего языка интерфейса. Примером таких макетов могут служить регламентированные формы отчетности для государственных учреждений. Например, пользователи с любым языком интерфейса должны формировать русскоязычную счет-фактуру – налоговый документ строго установленного образца в соответствии с Налоговым кодексом Российской Федерации (не существует российских счет-фактур на других языках, кроме русского).

              \n

              Для табличных и HTML-макетов, которые должны выводится пользователю и на печать строго на одном языке, следует

              \n
                \n
              • указывать в наименовании постфикс кода языка, аналогично п.1 \n
              • и устанавливать код языка макета аналогично п.2 при программном получении макета в коде.
              \n

              Такие макеты не должны переводиться на другие языки интерфейса. При программном формировании текстов для заполнения макета следует явно указывать второй параметр в функции НСтр() для того, чтобы строки были сформированы на том же языке, что и макет.

              \n

              Например, не правильно:

              Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура\");\n...\nОбласть.Текст = НСтр(\"ru='Заголовок печати';\");\n
              \n

              Правильно:

              \n

              Макет = ПолучитьМакет((\"ПФ_MXL_СчетФактура_ru\");
              Макет.КодЯзыка = Метаданные().Языки.Русский.КодЯзыка;
              ...
              Область.Текст = НСтр(\"ru='Заголовок печати';\", Метаданные().Языки.Русский.КодЯзыка);

              \n

              При использовании Библиотеки стандартных подсистем (БСП) и подсистемы Печать получение макета через функцию УправлениеПечатью.МакетПечатнойФормы(\"ПФ_MXL_СчетФактура\") позволяет получить форму ПФ_MXL_СчетФактура_ru и устанавливает у макета свойство КодЯзыка.

              \n

              4. Если в текстах макетов используются именованные параметры подстановки, необходимо соблюдать для них требования по локализации интерфейсных текстов в коде.

              \n

              5. Кодировку в макетах использовать UTF-8.

              \n

              6. Также, по возможности, следует группировать однотипные макеты (использовать один макет вместо нескольких). Например, в следующем примере в конфигурации имеется несколько однотипных макетов с сообщениями, но их содержимое записывается в один справочник, поэтому правильно хранить все подобные сообщения в одном макете.

              \n

              Неправильно:

               
              Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(\"Сообщение\");\n
              \n

              Правильно:

              \n

               

              Макет = Обработки.ПереключениеРежимов.ПолучитьМакет(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(\"Сообщения_%1\", ОбщегоНазначения.КодОсновногоЯзыка()));
              \n

              7. Внешние компоненты следует размешать в макетах с типом макета внешняя компонента. При разработке внешней компоненты требуется обрабатывать метод SetLocale для локализации внешней компоненты в соответствии с полученным кодом локализации (см. Технология создания внешних компонент). Если полученный код локализации отличается от предусмотренного во внешней компоненте, то компонента должна настроить свое окружение на использование английского языка.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "499", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Процедура переопределяемого общего модуля содержит лишний код (должен быть только код вида \"<ИмяМодуля>.<ИмяПроцедуры>(<Параметры>);\").", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "5", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Комментарий должен начинаться с прописной буквы.", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "500", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Имя вызываемой процедуры отличается от имени переопределяемой процедуры.", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "501", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Отличается состав или порядок параметров вызываемой и переопределяемой процедуры.", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "502", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Неверный комментарий у процедуры, вызываемой в переопределяемом модуле (должен быть \"См. <ПереопределяемыйМодуль>.<ПереопределяемаяПроцедура>.\").", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "503", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В переопределяемом общем модуле описана функция.", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "505", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В переопределяемом общем модуле описана неэкспортная процедура (функция).", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "506", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В переопределяемом общем модуле описана лишняя внешняя область (должна быть только область \"ПрограммныйИнтерфейс\").", +"Description": "

              Переопределение общих модулей в условиях иерархии библиотек

              #std554

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              При разработке нескольких библиотек, стоящих на поддержке друг у друга, следует минимизировать трудоемкость по обновлению кода переопределяемых общих модулей в каждой из библиотек. Для этого рекомендуется использовать следующую методику:

              \n

              1. В библиотеке нижнего уровня иерархии (самой базовой) объявляется переопределяемый модуль по общим правилам, изложенным выше.
              Например: БазоваяБиблиотекаПереопределяемый.

              \n

              2. В библиотеках более высокого уровня реализация процедур и функций переопределяемого модуля базовой библиотеки может быть при необходимости доопределена. При этом в переопределяемом модуле размещается не сама реализация (ее код), а только один вызов.

              \n

              Например, в общем модуле БазоваяБиблиотекаПереопределяемый в библиотеке верхнего уровня «Базовая библиотека» реализация фактически размещается в модуле МодульБазовойБиблиотеки:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              КонецПроцедуры

              \n

              в этом же общем модуле БазоваяБиблиотекаПереопределяемый в следующей библиотеке верхнего уровня «Библиотека второго уровня»:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              КонецПроцедуры

              \n

              и т.д.

              \n

              3. Таким образом, в конечной конфигурации-потребителе реализация переопределяемого модуля имеет вид:

              \n

              Процедура НастроитьИнтерфейс(Знач ПараметрыРаботы) Экспорт

              \n
              \n

              // Начало: Базовая библиотека
              МодульБазовойБиблиотеки.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Базовая библиотека

              \n

              // Начало: Библиотека второго уровня
              МодульБиблиотекиВторогоУровня.НастроитьИнтерфейс(ПараметрыРаботы);
              // Конец: Библиотека второго уровня

              \n

              // а теперь выполняем настройки так, как это надо нашей конфигурации
              // ...

              \n

              КонецПроцедуры

              \n

              Такой подход позволяет

              \n
                \n
              • скрыть от библиотек верхнего уровня и конфигураций-потребителей детали реализации библиотек более нижнего уровня, что минимизирует риск ошибки при обновлении кода переопределяемого общего модуля; \n
              • но при этом, в общем случае, оставляет возможность выбора: воспользоваться или отказаться от нее.
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "507", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Роль дает права на объекты других подсистем.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "508", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно заданы права на обработку (должны быть у ИспользованиеОбработки<ИмяОбработки>, БазовыеПрава<ИмяБиблиотеки> или Подсистема<ИмяПодсистемы>).", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "510", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Ни в одной роли нет прав на просмотр команды.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "511", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неверно заданы права на команду (есть права на просмотр команды, но нет прав на чтение или просмотр объекта).", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "512", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно заданы права на команду (есть права на чтение или просмотр объекта, но нет прав на просмотр команды).", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "513", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно заданы права на команду (права на команды печати должны быть назначены роли \"БазовыеПрава<ИмяБиблиотеки>\").", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "514", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Роль не дает прав ни на один объект метаданных, и к ней нет обращения в коде модулей.", +"Description": "

              Проверка прав доступа

              #std737

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

              \n
                \n
              • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
              • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
              \n

              Эти меры позволяют:

              \n
                \n
              • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
              • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
              • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
              \n

              2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

              \n

              3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
              Например, неправильно:

              \n

              Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
              Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

              \n

              правильно:

              \n

              Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
              Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

              \n

              Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

              \n

              4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
              Например, без использования БСП:

              \n

              Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

              \n

              Либо аналогичная проверка с использованием БСП:

              \n

              Если Пользователи.РолиДоступны(...) Тогда ...

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "515", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована функция \"Пользователи.РолиДоступны()\".", +"Description": "

              Проверка прав доступа

              #std737

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. В случае большого количества ролей в конфигурации (от нескольких десятков) не рекомендуется использовать ролевую настройку видимости в элементах форм (просмотр и редактирование реквизитов по ролям, пользовательскую видимость полей формы по ролям, использование команд по ролям). Вместо этого следует придерживаться следующих подходов:

              \n
                \n
              • при сильных различиях внешнего вида и функциональности формы в зависимости от наличия тех или иных ролей у пользователя – разрабатывать отдельные формы, специализированные под конкретный набор прав пользователя; \n
              • при незначительных отличиях – выполнять проверку прав в коде. При этом следует иметь в виду, что программное управление видимостью может снизить скорость открытия формы, что нужно учитывать при выборе между предлагаемыми подходами.
              \n

              Эти меры позволяют:

              \n
                \n
              • существенно упростить работу из кода с элементами управления, которые пропадают из коллекции Элементы (код Элементы.ИмяЭлемента.ИмяСвойства становится нерабочим); \n
              • повысить устойчивость кода к пересмотру состава ролей в конфигурации; \n
              • организовать контроль использования ролей в конфигурации (в противном случае, выполнять анализ прав доступа по флажкам, назначенных для ролей в различных элементах произвольных форм конфигурации, крайне затруднительно).
              \n

              2. Не рекомендуется использовать ролевую настройку видимости в  командном интерфейсе конфигурации, командном интерфейсе основного раздела, а также рабочей области начальной страницы. Вместо этого следует использовать настройку прав на разделы командного интерфейса, общие формы и объекты, включенные в командный интерфейс или в рабочую область. Это позволяет повысить предсказуемость поведения управляемого интерфейса для пользователя, а также упростить расследование ошибок.

              \n

              3. Для проверки прав доступа в коде следует использовать метод ПравоДоступа.
              Например, неправильно:

              \n

              Если РольДоступна(\"ДобавлениеИзменениеСтранМира\") Тогда ...
              Если РольДоступна(\"ПросмотрОтчетаПопулярныеСтраны\") Тогда ...

              \n

              правильно:

              \n

              Если ПравоДоступа(\"Редактирование\", Метаданные.Справочники.СтраныМира) Тогда ...
              Если ПравоДоступа(\"Просмотр\", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...

              \n

              Такой подход позволяет повысить устойчивость кода к пересмотру состава ролей в конфигурации.

              \n

              4. В тех случаях, где роль не дает никаких прав на объекты метаданных, а служит только для определения того или иного дополнительного права, следует использовать метод РольДоступна. При использовании в конфигурации Библиотеки стандартных подсистем (БСП) следует использовать функцию РолиДоступны общего модуля Пользователи:
              Например, без использования БСП:

              \n

              Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...

              \n

              Либо аналогичная проверка с использованием БСП:

              \n

              Если Пользователи.РолиДоступны(...) Тогда ...

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "518", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Планом обмена поддерживается версия формата обмена EnterpriseData, не входящая в состав конфигурации.", +"Description": "

              Интеграция прикладных решений через формат EnterpriseData

              #std771

              Область применения: управляемое приложение.

              \n

              1. Переходы с конфигурации на конфигурацию следует разрабатывать на основе правил конвертации (ПК). Обмены между конфигурациями, использующими Библиотеку стандартных подсистем (БСП), следует делать на основе формата EnterpriseData, разрабатывать новые обмены на основе ПК запрещается.

              \n

              2. Актуальные версии EnterpriseData содержатся в последней опубликованной версии конфигурации БСП в виде объектов метаданных Пакет XDTO, именуемых следующим образом: EnterpriseData_{X|XX}_{Y|YY}_{Z|ZZ}, где X, Y - это Major версия, Z - это Minor версия.

              \n

              Список актуальных версий поддерживается в состоянии, обеспечивающем оптимальный баланс между затратами на их поддержку в обменах и степенью совместимости версий прикладных решений.

              \n

              Например, версии 1.0, 1.1 EnterpriseData были сняты с поддержки, т.к. интервала 1.2-1.4 версий формата достаточно для обмена между версиями прикладных решений из достаточно широкого диапазона.

              \n

              3. При разработке новых версий прикладных решений нужно стремиться к тому, чтобы в обменах данными поддерживались все актуальные версии EnterpriseData. Это требование обеспечивает возможность асинхронного выпуска новых версий прикладных решений для разработчиков, а также возможность асинхронного перехода на них для пользователей. Исключение составляет случай, описанный в пункте 4.

              \n

              Запрещается выпускать версию конфигурации, не поддерживающую какую-либо из версий формата, поддерживаемых в версии БСП, встроенной в версию конфигурации.

              \n

              Пример:
              При выпуске конфигурации, в которую встроена версия 2.4.1 БСП, необходимо поддержать версии 1.2, 1.3 и 1.4 формата EnterpriseData.

              \n

              4. Версия формата EnterpriseData не должна поддерживаться в обмене данными, если она не соответствует требованиям к функциональности этого обмена.

              \n

              Пример:
              Для интеграции двух конфигураций необходим обмен документами «Чек ККМ». Поддержка передачи этих данных есть только в версии 1.4 формата, следовательно поддерживаемые в этом обмене версии формата должны быть не младше 1.4.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              5. В редких случаях обмен данными между прикладными решениями невозможен по причине отсутствия совместно поддерживаемых версий EnterpriseData, Например, такая ситуация может возникнуть, когда версия одного из прикладных решений, сильно устарела и требует обновления.
              В целях предотвращения данной проблемы рекомендуется информировать пользователей о том, какие версии EnterpriseData поддерживаются в прикладном решении.

              \n

              См. также

              \n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "519", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Планом обмена не поддерживается более высокая версия формата обмена EnterpriseData.", +"Description": "

              Интеграция прикладных решений через формат EnterpriseData

              #std771

              Область применения: управляемое приложение.

              \n

              1. Переходы с конфигурации на конфигурацию следует разрабатывать на основе правил конвертации (ПК). Обмены между конфигурациями, использующими Библиотеку стандартных подсистем (БСП), следует делать на основе формата EnterpriseData, разрабатывать новые обмены на основе ПК запрещается.

              \n

              2. Актуальные версии EnterpriseData содержатся в последней опубликованной версии конфигурации БСП в виде объектов метаданных Пакет XDTO, именуемых следующим образом: EnterpriseData_{X|XX}_{Y|YY}_{Z|ZZ}, где X, Y - это Major версия, Z - это Minor версия.

              \n

              Список актуальных версий поддерживается в состоянии, обеспечивающем оптимальный баланс между затратами на их поддержку в обменах и степенью совместимости версий прикладных решений.

              \n

              Например, версии 1.0, 1.1 EnterpriseData были сняты с поддержки, т.к. интервала 1.2-1.4 версий формата достаточно для обмена между версиями прикладных решений из достаточно широкого диапазона.

              \n

              3. При разработке новых версий прикладных решений нужно стремиться к тому, чтобы в обменах данными поддерживались все актуальные версии EnterpriseData. Это требование обеспечивает возможность асинхронного выпуска новых версий прикладных решений для разработчиков, а также возможность асинхронного перехода на них для пользователей. Исключение составляет случай, описанный в пункте 4.

              \n

              Запрещается выпускать версию конфигурации, не поддерживающую какую-либо из версий формата, поддерживаемых в версии БСП, встроенной в версию конфигурации.

              \n

              Пример:
              При выпуске конфигурации, в которую встроена версия 2.4.1 БСП, необходимо поддержать версии 1.2, 1.3 и 1.4 формата EnterpriseData.

              \n

              4. Версия формата EnterpriseData не должна поддерживаться в обмене данными, если она не соответствует требованиям к функциональности этого обмена.

              \n

              Пример:
              Для интеграции двух конфигураций необходим обмен документами «Чек ККМ». Поддержка передачи этих данных есть только в версии 1.4 формата, следовательно поддерживаемые в этом обмене версии формата должны быть не младше 1.4.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              5. В редких случаях обмен данными между прикладными решениями невозможен по причине отсутствия совместно поддерживаемых версий EnterpriseData, Например, такая ситуация может возникнуть, когда версия одного из прикладных решений, сильно устарела и требует обновления.
              В целях предотвращения данной проблемы рекомендуется информировать пользователей о том, какие версии EnterpriseData поддерживаются в прикладном решении.

              \n

              См. также

              \n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "520", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Планом обмена не поддерживается более низкая версия формата обмена EnterpriseData.", +"Description": "

              Интеграция прикладных решений через формат EnterpriseData

              #std771

              Область применения: управляемое приложение.

              \n

              1. Переходы с конфигурации на конфигурацию следует разрабатывать на основе правил конвертации (ПК). Обмены между конфигурациями, использующими Библиотеку стандартных подсистем (БСП), следует делать на основе формата EnterpriseData, разрабатывать новые обмены на основе ПК запрещается.

              \n

              2. Актуальные версии EnterpriseData содержатся в последней опубликованной версии конфигурации БСП в виде объектов метаданных Пакет XDTO, именуемых следующим образом: EnterpriseData_{X|XX}_{Y|YY}_{Z|ZZ}, где X, Y - это Major версия, Z - это Minor версия.

              \n

              Список актуальных версий поддерживается в состоянии, обеспечивающем оптимальный баланс между затратами на их поддержку в обменах и степенью совместимости версий прикладных решений.

              \n

              Например, версии 1.0, 1.1 EnterpriseData были сняты с поддержки, т.к. интервала 1.2-1.4 версий формата достаточно для обмена между версиями прикладных решений из достаточно широкого диапазона.

              \n

              3. При разработке новых версий прикладных решений нужно стремиться к тому, чтобы в обменах данными поддерживались все актуальные версии EnterpriseData. Это требование обеспечивает возможность асинхронного выпуска новых версий прикладных решений для разработчиков, а также возможность асинхронного перехода на них для пользователей. Исключение составляет случай, описанный в пункте 4.

              \n

              Запрещается выпускать версию конфигурации, не поддерживающую какую-либо из версий формата, поддерживаемых в версии БСП, встроенной в версию конфигурации.

              \n

              Пример:
              При выпуске конфигурации, в которую встроена версия 2.4.1 БСП, необходимо поддержать версии 1.2, 1.3 и 1.4 формата EnterpriseData.

              \n

              4. Версия формата EnterpriseData не должна поддерживаться в обмене данными, если она не соответствует требованиям к функциональности этого обмена.

              \n

              Пример:
              Для интеграции двух конфигураций необходим обмен документами «Чек ККМ». Поддержка передачи этих данных есть только в версии 1.4 формата, следовательно поддерживаемые в этом обмене версии формата должны быть не младше 1.4.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              5. В редких случаях обмен данными между прикладными решениями невозможен по причине отсутствия совместно поддерживаемых версий EnterpriseData, Например, такая ситуация может возникнуть, когда версия одного из прикладных решений, сильно устарела и требует обновления.
              В целях предотвращения данной проблемы рекомендуется информировать пользователей о том, какие версии EnterpriseData поддерживаются в прикладном решении.

              \n

              См. также

              \n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "521", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Нарушена схема работы с транзакциями: преждевременный выход из блока \"Попытка..Исключение\" без завершения или отмены транзакции.", +"Description": "

              Транзакции: правила использования

              #std783

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.

              \n

              1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:

              \n\n

              Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.

              \n

              1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.

              \n

              1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода

              \n

              Правильно

              \n

              Процедура ЗаписатьДанныеВИБ()

              \n

                  НачатьТранзакцию();

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                      ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              Неправильно

              \n

              Процедура ЗаписатьДанныеВИБ()
               
                  НачатьТранзакцию();
                  ЗаписатьДокумент();

              \n

              КонецПроцедуры;

              \n

              Процедура ЗаписатьДокумент()

              \n

                  Попытка
                      ... // чтение или запись данных
                      ДокументОбъект.Записать()
                      ЗафиксироватьТранзакцию();
                  Исключение
                      ОтменитьТранзакцию();
                  ... // дополнительные действия по обработке исключения
                  КонецПопытки;

              \n

              КонецПроцедуры

              \n

              1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:

              \n
                \n
              • \n
                метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка;
                \n
              • \n
                все действия, выполняемые после вызова метода НачатьТранзакцию, должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных;
                \n
              • \n
                метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение, чтобы  гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение;
                \n
              • \n
                необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию, а затем выполнять другие действия, если они требуются;
                \n
              • \n
                рекомендуется в блоке Исключение делать запись в журнал регистрации;
                \n
              • \n
                при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение.  В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»
              \n

              Пример

              \n

              НачатьТранзакцию();
              Попытка
                  БлокировкаДанных = Новый БлокировкаДанных;
                  ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(\"Документ.ПриходнаяНакладная\");
                  ЭлементБлокировкиДанных.УстановитьЗначение(\"Ссылка\", СсылкаДляОбработки);
                  ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
                  БлокировкаДанных.Заблокировать();

              \n

                  ... // чтение или запись данных

                  ДокументОбъект.Записать();

              \n

                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();

              \n

                  ЗаписьЖурналаРегистрации(НСтр(\"ru = 'Выполнение операции'\"),
                      УровеньЖурналаРегистрации.Ошибка,
                      ,
                      ,
                      ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

              \n

                  ВызватьИсключение; // есть внешняя транзакция

              \n

              КонецПопытки;

              \n

              1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.

              \n

              1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию, когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.

              \n

              Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).

              \n

              При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию.

              \n

              Правильно

              \n

              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
              Исключение
                  ... // действия по обработке исключения
              КонецПопытки;

              \n

              Неправильно

              \n

              НачатьТранзакцию();
              Попытка
                  ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
                  ... // действия по заполнению объекта
                  ДокументОбъект.Записать();
                  ЗафиксироватьТранзакцию();
              Исключение
                  ОтменитьТранзакцию();
              КонецПопытки;

              \n

              1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью, ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.

              \n

              1.4.3. При необходимости повысить качество сообщений об ошибках – на каждом уровне разработчик может предусмотреть свою обработку исключений, для чего, возможно, потребуется открыть вложенную транзакцию.

              \n

              Пример

              \n

              Вызывается метод ДобавитьЭлектроннуюПодпись. Внутри, если что-то пошло не так, нужно обработать исключение и добавить текст вида: «Не удалось добавить электронную подпись к объекту %ПредставлениеОбъекта% по причине:%ОписаниеОшибки%». В противном случае исключение будет обработано выше по стеку вызовов, например, при записи файла и будет выдано сообщение вида: «Не удалось записать файл %ИмяФайла% по причине: %ОписаниеОшибки%», где в «%ОписаниеОшибки%», будет просто указание на строчку кода и пользователю будет не понятно, зачем вообще программа записывала файл, если он просто его подписывал.

              \n

              1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.

              \n

              2. Ограничение на длину транзакции.

              \n

              2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.

              \n

              Пример

              \n

              При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.

              \n

              2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.

              \n

              2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.

              \n

              2.2. Следует избегать транзакций, которые выполняются длительное время.

              \n

              Пример

              \n

              Неправильно

              \n

              Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.

              \n

              Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.

              \n

              Правильно

              \n

              Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.

              \n

              См. также Особенности использования транзакций при обмене данными

              \n

              2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:

              \n
                \n
              • в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию; \n
              • блокировки, установленные в транзакции, остаются до конца транзакции; \n
              • на сервере 1С:Предприятия блокировки занимают оперативную память; \n
              • другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
              \n

              Все это в целом может снижать эффективность использования ресурсов.

              \n

              2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.

              \n

              Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях

              \n
                \n
              • \n
                возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4);
                \n
              • \n
                если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения;
                \n
              • \n
                так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации)
              \n

              2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:

              \n
                \n
              • \n
                сложные, ресурсоемкие расчеты нужно стремиться делать до начала транзакции, если это позволяет бизнес-логика;
                \n
              • \n
                если расчет должен выполняться в транзакции, то нужно стремиться сделать его как можно более простым. Например, контроль остатков можно делать уже после записи простым запросом к записываемому регистру;
                \n
              • \n
                проверка заполнения объекта должна делаться вне транзакции (см. Проверки, выполняемые в и вне транзакции записи объекта);
                \n
              • \n
                запросы, перед выполнением которых не нужно устанавливать блокировку данных, нужно стремиться выполнять до начала транзакции (см. Ответственное чтение данных);
                \n
              • \n
                запросы, выполняемые в рамках транзакций нужно стремиться оптимизировать (см. группу стандартов Оптимизация запросов)
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 15 +}, +{ +"Code": "524", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Некорректно заполнено свойство \"Путь к данным\" у поля динамического списка.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "525", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Некорректно заполнено свойство \"Данные\" у кнопки, связанной с полем динамического списка.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "526", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "У процедуры (функции) в модуле формы отсутствует директива компиляции.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "527", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В качестве параметра обработчика оповещения указана серверная процедура.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "529", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Для объекта метаданных назначено несколько отложенных обработчиков обновления в параллельном режиме.", +"Description": "

              Параллельный режим отложенного обновления

              \n
              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС.
              Для БСП версии 2.3.2 и выше

              \n

              1. Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • \n
                Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. Подробнее об этом режиме обновления см. Отложенное обновление данных.
                \n
              • \n
                Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий).
              \n

              2.1. В тех конфигурациях, большая часть данных которых обрабатывается отложенно, целесообразно использовать параллельный режим выполнения отложенных обработчиков. Это позволит выполнять обновление данных конфигурации более равномерно.

              Включение данного режима выполняется в процедуре ПриДобавленииПодсистемы общего модуля ОбновлениеИнформационнойБазыХХХ. Для этого необходимо установить свойству РежимВыполненияОтложенныхОбработчиков значение Параллельно, например:

              \n

              Описание.Имя = \"БиблиотекаСтандартныхПодсистемДемо\";
              Описание.Версия = \"2.3.1.60\";
              Описание.РежимВыполненияОтложенныхОбработчиков = \"Параллельно\";

              \n

              2.2. Если в состав конфигурации входит одна или несколько библиотек, то рекомендуется переводить на параллельный режим обновления все библиотеки, входящие в состав конфигурации.

              \n

              В противном случае, отложенные обработчики библиотеки, у которых не установлен режим параллельного обновления или не заполнен список библиотек, с которыми они могут обновляться параллельно, будут выполняться последовательно и независимо друг от друга. Таким образом, пока не обновится одна библиотека, обновление других не начнется, что может сильно отодвинуть начало обновления основных данных информационной базы. Например, подсистема «Версионирование объектов» одной из библиотек может выполнять длительную реструктуризацию сведений об архивных версиях объектах, что увеличивает время недоступности основных данных информационной базы, необходимых для работы пользователей.

              \n

              Например, для того чтобы отложенное обновление данных основной конфигурации выполнялось параллельно с обновлением «торговых» данных библиотеки УправлениеТорговлей следует указать:

              \n

              Описание.ОбновлятьПараллельноСПодсистемами.Добавить(\"УправлениеТорговлей\");

              \n

              3.1. Разработка отложенных обработчиков для параллельного режима обновления значительно отличается от разработки для последовательного режима, поэтому при переходе конфигурации (библиотеки) с последовательного на параллельный режим обновления потребуется пересмотр реализации всех отложенных обработчиков.

              \n

              Отложенные обработчики обновления предварительно регистрируют все обновляемые данные в специальном плане обмена ОбновлениеИнформационнойБазы, а в дальнейшем, после завершения их обработки, снимают их с регистрации. Для этого необходимо включить в состав данного плана обмена все обновляемые объекты (как правило, это все объекты конфигурации), а при добавлении отложенного обработчика ему необходимо задать новые свойства ПроцедураЗаполненияДанныхОбновления и ОчередьОтложеннойОбработки. Например:

              \n

              Обработчик = Обработчики.Добавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Документы.ЗаказПокупателя.ОбработатьДанныеДляПереходаНаНовуюВерсию\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");
              Обработчик.ПроцедураЗаполненияДанныхОбновления = \"Документы.ЗаказПокупателя.ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию\";
              Обработчик.ОчередьОтложеннойОбработки = 1;

              \n

              Рассмотрим обработку данных в параллельном режиме на примере.

              \n

              Есть два обработчика – «Обновление реквизитов Документа» (Обработчик 1) и «Обновление движений Документа по Регистру, в т. ч. по данным обновленных реквизитов» (Обработчик 2)
              По сути обработчиков конкретный документ должен сначала быть обработан Обработчиком 1, а затем переписаны движения Обработчиком 2
              После анализа Обработчику 1 присвоена очередь №1, а Обработчику 2 – очередь №2
              После выполнения всех монопольных обработчиков запускаются процедуры регистрации, написанные отдельно Обработчика №1 и Обработчика №2. Процедуры регистрации анализируют состояние базы и регистрируют к обработке:

              \n
                \n
              • \n
                Обработчик 1 на узле по очереди №1 служебного плана обмена Обновление информационной базы регистрирует все Документы, в которых нужно обновить реквизиты
                \n
              • \n
                Обработчик 2 на узле по очереди №2 регистрирует все регистраторы, по которым нужно обновить движения
              \n

              Монопольная часть обновления завершается, пользователи могут входить в программу и работать.

              \n

              В фоне стартует отложенное обновление:

              \n
                \n
              • \n
                Запускается обработчик №1. Из данных на узле по очереди №1 выбирается первая порция документов для обработки обработчиком 1. Данные обрабатываются, при этом удаляется регистрация Документов на узле по очереди №1.
                \n
              • \n
                Запускается обработчик №2. Этот обработчик может работать с документами, которые уже обработаны Обработчиком №1 (либо вообще не будут им обрабатываться): из данных, зарегистрированных на узле по очереди №2 выбирается первая порция регистраторов, удовлетворяющих этим условиям. При выполнении обработчика 2 удаляется регистрация на узле по очереди №2.
                \n
              • \n
                Опять запускается обработчик №1, если на узле по очереди №1 еще есть зарегистрированные данные.
                \n
              • \n
                и т.д. пока ни на одном узле не останется зарегистрированных к обработке данных.
              \n

              3.2. ПроцедураЗаполненияДанныхОбновления (Строка) – процедура, регистрирующая объекты, которые обработчик будет обрабатывать. Например, для обработчика, заполняющего значение нового реквизита СтатусЗаказа документа ЗаказПокупателя, процедура регистрации будет выглядеть так:

              \n

              Процедура ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры)
               
               Запрос = Новый Запрос;
               Запрос.Текст =
                \"ВЫБРАТЬ
                | ЗаказПокупателя.Ссылка КАК Ссылка
                |ИЗ
                | Документ.ЗаказПокупателя КАК ЗаказПокупателя
                |ГДЕ
                | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка\";
               Запрос.Параметры.Вставить(\"ПустаяСсылка\", Перечисления.СтатусыЗаказовПокупателей.ПустаяСсылка());
               
               Результат = Запрос.Выполнить().Выгрузить();
               МассивСсылок = Результат.ВыгрузитьКолонку(\"Ссылка\");
               
               ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, МассивСсылок);
              КонецПроцедуры

              \n

              3.3. ОчередьОтложеннойОбработки (Число) – задается по результатам анализа отложенных обработчиков, если обработчик не зависит от других по читаемым или обрабатываемым данным, то следует указывать значение 1. Если же при обработке данных обработчик опирается на результат выполнения другого обработчика (пересекается по читаемым или обрабатываемым метаданным), то ему следует указывать более высокое значение очереди. Например:

              \n

              Обработчик.ОчередьОтложеннойОбработки = 2;

              \n

              Для построения очередей рекомендуется использовать конфигурацию СППР (Система проектирования прикладных решений), которая на основании заполненной разработчиками информации о читаемых и изменяемых обработчиками данных присваивает очереди. Стоит учитывать, что при добавлении новых обработчиков значение очереди для уже существующих может изменяться.

              Порядок обновления данных не зависит от версии, на которую зарегистрирован обработчик, и выполняется от минимальной очереди к максимальной, т.е. сначала будут обработаны первые порции данных обработчиками первой очереди, затем второй и так далее. Таким образом, при вызове обработчика, который зависит от других, у него уже имеется массив входных данных (обработанный обработчиками предыдущих очередей), который он сможет обновить.

              Рекомендуется избегать повторной (многократной) обработки одного объекта несколькими обработчиками обновления. В частности, в ситуации, когда очередь – всего одна, все данные информационной базы обновляются параллельно и равномерно.

              Если в состав конфигурации входит одна или несколько библиотек, то нумерация очередей должна быть сквозная для всех библиотек.

              4.1. Общая схема реализации отложенного обработчика обновления для конфигурации (библиотеки) с параллельным режимом обновления выглядит следующим образом:

              \n
                \n
              • \n
                Перед началом обработки данных, вначале процедуры обработчика обновления, необходимо явным образом проверить, обновлены ли необходимые для его работы данные, т.к. могут быть другие отложенные обработчики меньшей очереди, которые обрабатывают те же данные. Для этого необходимо воспользоваться методами программного интерфейса общего модуля ОбновлениеИнформационнойБазы. Например, для получения выборки доступных для обработки данных ссылочного типа необходимо использовать метод ВыбратьСсылкиДляОбработки
                \n
              • \n
                После завершения обработки необходимо проверить, все ли данные были обновлены или требуется повторный вызов процедуры обновления, для чего нужно вызвать функцию ОбработкаДанныхЗавершена и явно заполнить значение параметра Параметры.ОбработкаЗавершена.
              \n

              Например:

              \n

              Процедура ОбработатьДанныеДляПереходаНаНовуюВерсию(Параметры) Экспорт
                 Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь, \"Документ.ЗаказПокупателя\");
                 Пока Выборка.Следующий() Цикл

              \n

               НачатьТранзакцию();
               Попытка
                        // обработка данных
                        ………
               КонецПопытки;
                 КонецЦикла;

              \n

                 Параметры.ОбработкаЗавершена = ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, \"Документ.ЗаданиеНаПеревозку\");
              КонецПроцедуры

              \n

              4.2. Запись данных обработчиком обновления должна производится с помощью специализированных методов модуля ОбновлениеИнформационнойБазы (ЗаписатьДанные, ЗаписатьОбъект, ЗаписатьНаборЗаписей) – тогда будет автоматически отменяться регистрация данных в специальном плане обмена ОбновлениеИнформационнойБазы.

              \n

              4.3. Если при выполнении обработчика выясняется, что зарегистрированный к обработке объект уже не нужно обновлять (перезаписывать), то необходимо обязательно отметить регистрацию объекта в служебном обмена ОбновлениеИнформационнойБазы, иначе произойдет зацикливание обработчика обновления. Это нужно делать, используя метод ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки.

              \n

              5. Каждый раз при выпуске новых версий конфигурации требуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики, как это было возможно в последовательном режиме), а также пересматривать нумерацию очередей. Поэтому для уменьшения количества пересматриваемых обработчиков следует избегать (минимизировать) обновление через несколько версий (третья цифра номера релиза), введя обязательные промежуточные версии, через которые нельзя проскочить.

              \n

              6. Если отложенный обработчик обрабатывает не только архивные данные, но и данные текущего периода, то для предотвращения некорректной работы программы рекомендуется блокировать еще не обработанные данные от изменения пользователями программы, а также отчеты и обработки, которые могут некорректно работать до завершения отложенного обновления этих данных.

              \n

              Для этого необходимо:

              \n
                \n
              • в свойстве БлокируемыеОбъекты отложенного обработчика обновления следует указать те объекты метаданных, с которыми он работает (читает или записывает), а также связанные с ними отчеты и обработки; \n
              • в свойстве ПроцедураПроверки указать имя экспортной функции, которая дополнительно проверяет, нужно ли блокировать конкретный объект.
              \n

              Например:

              \n

              Обработчик.ПроцедураПроверки = \"Документы.ЗаказПокупателя.ДанныеОбновленыНаНовуюВерсиюПрограммы\";
              Обработчик.БлокируемыеОбъекты = \"Документ.ЗаказПокупателя, Отчет.СтатусыЗаказовПокупателей\";

              \n

              В общем случае, в качестве процедуры проверки можно использовать стандартный метод ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы, который проверяет, зарегистрирован ли объект в плане обмена ОбновлениеИнформационнойБазы и если нет, то считает, что он уже обновлен. Если такой проверки недостаточно, то нужно делать отдельную.

              \n

              Процедура проверки принимает на вход параметр типа Структура, свойства которой идентифицируют запрашиваемый объект:

              \n
                \n
              • Данные (ЛюбаяСсылка, НаборЗаписей, Объект, ДанныеФормыСтруктура) - объект, который нужно проверить, обработан ли он данным отложенным обработчиком обновления или еще нет; \n
              • МетаданныеОбъекта (ОбъектМетаданных) - объект метаданных, соответствующий параметру Данные; \n
              • ПолноеИмя (Строка) - полное имя объекта метаданных; \n
              • Отбор (ЛюбаяСсылка, Структура) - если Данные - это ссылочный объект, то значение ссылки; если регистр подчиненный регистратору - значение отбора по регистратору. Если Данные - это независимый регистр сведений, то в этом параметре предается структура, соответствующая установленным отборам по измерениям. \n
              • ЭтоНовый (Булево) - если Данные - это ссылочный объект, то признак нового объекта. Для других типов - всегда Ложь.
              \n

              Помимо этого для всех объектов, указанных в свойстве БлокируемыеОбъекты, необходимо добавить вызов процедуры ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан в обработчике события модуля формы объекта ПриСозданииНаСервере и в обработчике события модуля объекта ПередЗаписью:

              \n

              Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
               
               Если Параметры.Свойство(\"АвтоТест\") Тогда // Возврат при получении формы для анализа.
                Возврат;
               КонецЕсли;
               
               ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(Объект, ЭтотОбъект);
               …
              КонецПроцедуры

              \n

              Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
               
               Если ОбменДанными.Загрузка Тогда
                Возврат;
               КонецЕсли;
               
               ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(ЭтотОбъект);
               …
              КонецПроцедуры

              \n

              7. Обработчики обновления, процедуры заполнения данных обновления и процедуры проверки рекомендуется располагать в модулях менеджера обновляемых объектов, а в качестве имен для них использовать следующие:

              \n

              • Обработчики обновления (Обработчик.Процедура) – ОбработатьДанныеДляПереходаНаНовуюВерсию.
              • Процедуры заполнения данных обновления (Обработчик.ПроцедураЗаполненияДанныхОбновления) – ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию.
              • Процедуры проверки (Обработчик.ПроцедураПроверки) – ДанныеОбновленыНаНовуюВерсиюПрограммы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "530", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отложенный обработчик обновления в параллельном режиме для объекта одной подсистемы обрабатывает данные другой подсистемы.", +"Description": "

              Параллельный режим отложенного обновления

              \n
              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС.
              Для БСП версии 2.3.2 и выше

              \n

              1. Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • \n
                Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. Подробнее об этом режиме обновления см. Отложенное обновление данных.
                \n
              • \n
                Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий).
              \n

              2.1. В тех конфигурациях, большая часть данных которых обрабатывается отложенно, целесообразно использовать параллельный режим выполнения отложенных обработчиков. Это позволит выполнять обновление данных конфигурации более равномерно.

              Включение данного режима выполняется в процедуре ПриДобавленииПодсистемы общего модуля ОбновлениеИнформационнойБазыХХХ. Для этого необходимо установить свойству РежимВыполненияОтложенныхОбработчиков значение Параллельно, например:

              \n

              Описание.Имя = \"БиблиотекаСтандартныхПодсистемДемо\";
              Описание.Версия = \"2.3.1.60\";
              Описание.РежимВыполненияОтложенныхОбработчиков = \"Параллельно\";

              \n

              2.2. Если в состав конфигурации входит одна или несколько библиотек, то рекомендуется переводить на параллельный режим обновления все библиотеки, входящие в состав конфигурации.

              \n

              В противном случае, отложенные обработчики библиотеки, у которых не установлен режим параллельного обновления или не заполнен список библиотек, с которыми они могут обновляться параллельно, будут выполняться последовательно и независимо друг от друга. Таким образом, пока не обновится одна библиотека, обновление других не начнется, что может сильно отодвинуть начало обновления основных данных информационной базы. Например, подсистема «Версионирование объектов» одной из библиотек может выполнять длительную реструктуризацию сведений об архивных версиях объектах, что увеличивает время недоступности основных данных информационной базы, необходимых для работы пользователей.

              \n

              Например, для того чтобы отложенное обновление данных основной конфигурации выполнялось параллельно с обновлением «торговых» данных библиотеки УправлениеТорговлей следует указать:

              \n

              Описание.ОбновлятьПараллельноСПодсистемами.Добавить(\"УправлениеТорговлей\");

              \n

              3.1. Разработка отложенных обработчиков для параллельного режима обновления значительно отличается от разработки для последовательного режима, поэтому при переходе конфигурации (библиотеки) с последовательного на параллельный режим обновления потребуется пересмотр реализации всех отложенных обработчиков.

              \n

              Отложенные обработчики обновления предварительно регистрируют все обновляемые данные в специальном плане обмена ОбновлениеИнформационнойБазы, а в дальнейшем, после завершения их обработки, снимают их с регистрации. Для этого необходимо включить в состав данного плана обмена все обновляемые объекты (как правило, это все объекты конфигурации), а при добавлении отложенного обработчика ему необходимо задать новые свойства ПроцедураЗаполненияДанныхОбновления и ОчередьОтложеннойОбработки. Например:

              \n

              Обработчик = Обработчики.Добавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Документы.ЗаказПокупателя.ОбработатьДанныеДляПереходаНаНовуюВерсию\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");
              Обработчик.ПроцедураЗаполненияДанныхОбновления = \"Документы.ЗаказПокупателя.ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию\";
              Обработчик.ОчередьОтложеннойОбработки = 1;

              \n

              Рассмотрим обработку данных в параллельном режиме на примере.

              \n

              Есть два обработчика – «Обновление реквизитов Документа» (Обработчик 1) и «Обновление движений Документа по Регистру, в т. ч. по данным обновленных реквизитов» (Обработчик 2)
              По сути обработчиков конкретный документ должен сначала быть обработан Обработчиком 1, а затем переписаны движения Обработчиком 2
              После анализа Обработчику 1 присвоена очередь №1, а Обработчику 2 – очередь №2
              После выполнения всех монопольных обработчиков запускаются процедуры регистрации, написанные отдельно Обработчика №1 и Обработчика №2. Процедуры регистрации анализируют состояние базы и регистрируют к обработке:

              \n
                \n
              • \n
                Обработчик 1 на узле по очереди №1 служебного плана обмена Обновление информационной базы регистрирует все Документы, в которых нужно обновить реквизиты
                \n
              • \n
                Обработчик 2 на узле по очереди №2 регистрирует все регистраторы, по которым нужно обновить движения
              \n

              Монопольная часть обновления завершается, пользователи могут входить в программу и работать.

              \n

              В фоне стартует отложенное обновление:

              \n
                \n
              • \n
                Запускается обработчик №1. Из данных на узле по очереди №1 выбирается первая порция документов для обработки обработчиком 1. Данные обрабатываются, при этом удаляется регистрация Документов на узле по очереди №1.
                \n
              • \n
                Запускается обработчик №2. Этот обработчик может работать с документами, которые уже обработаны Обработчиком №1 (либо вообще не будут им обрабатываться): из данных, зарегистрированных на узле по очереди №2 выбирается первая порция регистраторов, удовлетворяющих этим условиям. При выполнении обработчика 2 удаляется регистрация на узле по очереди №2.
                \n
              • \n
                Опять запускается обработчик №1, если на узле по очереди №1 еще есть зарегистрированные данные.
                \n
              • \n
                и т.д. пока ни на одном узле не останется зарегистрированных к обработке данных.
              \n

              3.2. ПроцедураЗаполненияДанныхОбновления (Строка) – процедура, регистрирующая объекты, которые обработчик будет обрабатывать. Например, для обработчика, заполняющего значение нового реквизита СтатусЗаказа документа ЗаказПокупателя, процедура регистрации будет выглядеть так:

              \n

              Процедура ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры)
               
               Запрос = Новый Запрос;
               Запрос.Текст =
                \"ВЫБРАТЬ
                | ЗаказПокупателя.Ссылка КАК Ссылка
                |ИЗ
                | Документ.ЗаказПокупателя КАК ЗаказПокупателя
                |ГДЕ
                | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка\";
               Запрос.Параметры.Вставить(\"ПустаяСсылка\", Перечисления.СтатусыЗаказовПокупателей.ПустаяСсылка());
               
               Результат = Запрос.Выполнить().Выгрузить();
               МассивСсылок = Результат.ВыгрузитьКолонку(\"Ссылка\");
               
               ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, МассивСсылок);
              КонецПроцедуры

              \n

              3.3. ОчередьОтложеннойОбработки (Число) – задается по результатам анализа отложенных обработчиков, если обработчик не зависит от других по читаемым или обрабатываемым данным, то следует указывать значение 1. Если же при обработке данных обработчик опирается на результат выполнения другого обработчика (пересекается по читаемым или обрабатываемым метаданным), то ему следует указывать более высокое значение очереди. Например:

              \n

              Обработчик.ОчередьОтложеннойОбработки = 2;

              \n

              Для построения очередей рекомендуется использовать конфигурацию СППР (Система проектирования прикладных решений), которая на основании заполненной разработчиками информации о читаемых и изменяемых обработчиками данных присваивает очереди. Стоит учитывать, что при добавлении новых обработчиков значение очереди для уже существующих может изменяться.

              Порядок обновления данных не зависит от версии, на которую зарегистрирован обработчик, и выполняется от минимальной очереди к максимальной, т.е. сначала будут обработаны первые порции данных обработчиками первой очереди, затем второй и так далее. Таким образом, при вызове обработчика, который зависит от других, у него уже имеется массив входных данных (обработанный обработчиками предыдущих очередей), который он сможет обновить.

              Рекомендуется избегать повторной (многократной) обработки одного объекта несколькими обработчиками обновления. В частности, в ситуации, когда очередь – всего одна, все данные информационной базы обновляются параллельно и равномерно.

              Если в состав конфигурации входит одна или несколько библиотек, то нумерация очередей должна быть сквозная для всех библиотек.

              4.1. Общая схема реализации отложенного обработчика обновления для конфигурации (библиотеки) с параллельным режимом обновления выглядит следующим образом:

              \n
                \n
              • \n
                Перед началом обработки данных, вначале процедуры обработчика обновления, необходимо явным образом проверить, обновлены ли необходимые для его работы данные, т.к. могут быть другие отложенные обработчики меньшей очереди, которые обрабатывают те же данные. Для этого необходимо воспользоваться методами программного интерфейса общего модуля ОбновлениеИнформационнойБазы. Например, для получения выборки доступных для обработки данных ссылочного типа необходимо использовать метод ВыбратьСсылкиДляОбработки
                \n
              • \n
                После завершения обработки необходимо проверить, все ли данные были обновлены или требуется повторный вызов процедуры обновления, для чего нужно вызвать функцию ОбработкаДанныхЗавершена и явно заполнить значение параметра Параметры.ОбработкаЗавершена.
              \n

              Например:

              \n

              Процедура ОбработатьДанныеДляПереходаНаНовуюВерсию(Параметры) Экспорт
                 Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь, \"Документ.ЗаказПокупателя\");
                 Пока Выборка.Следующий() Цикл

              \n

               НачатьТранзакцию();
               Попытка
                        // обработка данных
                        ………
               КонецПопытки;
                 КонецЦикла;

              \n

                 Параметры.ОбработкаЗавершена = ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, \"Документ.ЗаданиеНаПеревозку\");
              КонецПроцедуры

              \n

              4.2. Запись данных обработчиком обновления должна производится с помощью специализированных методов модуля ОбновлениеИнформационнойБазы (ЗаписатьДанные, ЗаписатьОбъект, ЗаписатьНаборЗаписей) – тогда будет автоматически отменяться регистрация данных в специальном плане обмена ОбновлениеИнформационнойБазы.

              \n

              4.3. Если при выполнении обработчика выясняется, что зарегистрированный к обработке объект уже не нужно обновлять (перезаписывать), то необходимо обязательно отметить регистрацию объекта в служебном обмена ОбновлениеИнформационнойБазы, иначе произойдет зацикливание обработчика обновления. Это нужно делать, используя метод ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки.

              \n

              5. Каждый раз при выпуске новых версий конфигурации требуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики, как это было возможно в последовательном режиме), а также пересматривать нумерацию очередей. Поэтому для уменьшения количества пересматриваемых обработчиков следует избегать (минимизировать) обновление через несколько версий (третья цифра номера релиза), введя обязательные промежуточные версии, через которые нельзя проскочить.

              \n

              6. Если отложенный обработчик обрабатывает не только архивные данные, но и данные текущего периода, то для предотвращения некорректной работы программы рекомендуется блокировать еще не обработанные данные от изменения пользователями программы, а также отчеты и обработки, которые могут некорректно работать до завершения отложенного обновления этих данных.

              \n

              Для этого необходимо:

              \n
                \n
              • в свойстве БлокируемыеОбъекты отложенного обработчика обновления следует указать те объекты метаданных, с которыми он работает (читает или записывает), а также связанные с ними отчеты и обработки; \n
              • в свойстве ПроцедураПроверки указать имя экспортной функции, которая дополнительно проверяет, нужно ли блокировать конкретный объект.
              \n

              Например:

              \n

              Обработчик.ПроцедураПроверки = \"Документы.ЗаказПокупателя.ДанныеОбновленыНаНовуюВерсиюПрограммы\";
              Обработчик.БлокируемыеОбъекты = \"Документ.ЗаказПокупателя, Отчет.СтатусыЗаказовПокупателей\";

              \n

              В общем случае, в качестве процедуры проверки можно использовать стандартный метод ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы, который проверяет, зарегистрирован ли объект в плане обмена ОбновлениеИнформационнойБазы и если нет, то считает, что он уже обновлен. Если такой проверки недостаточно, то нужно делать отдельную.

              \n

              Процедура проверки принимает на вход параметр типа Структура, свойства которой идентифицируют запрашиваемый объект:

              \n
                \n
              • Данные (ЛюбаяСсылка, НаборЗаписей, Объект, ДанныеФормыСтруктура) - объект, который нужно проверить, обработан ли он данным отложенным обработчиком обновления или еще нет; \n
              • МетаданныеОбъекта (ОбъектМетаданных) - объект метаданных, соответствующий параметру Данные; \n
              • ПолноеИмя (Строка) - полное имя объекта метаданных; \n
              • Отбор (ЛюбаяСсылка, Структура) - если Данные - это ссылочный объект, то значение ссылки; если регистр подчиненный регистратору - значение отбора по регистратору. Если Данные - это независимый регистр сведений, то в этом параметре предается структура, соответствующая установленным отборам по измерениям. \n
              • ЭтоНовый (Булево) - если Данные - это ссылочный объект, то признак нового объекта. Для других типов - всегда Ложь.
              \n

              Помимо этого для всех объектов, указанных в свойстве БлокируемыеОбъекты, необходимо добавить вызов процедуры ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан в обработчике события модуля формы объекта ПриСозданииНаСервере и в обработчике события модуля объекта ПередЗаписью:

              \n

              Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
               
               Если Параметры.Свойство(\"АвтоТест\") Тогда // Возврат при получении формы для анализа.
                Возврат;
               КонецЕсли;
               
               ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(Объект, ЭтотОбъект);
               …
              КонецПроцедуры

              \n

              Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
               
               Если ОбменДанными.Загрузка Тогда
                Возврат;
               КонецЕсли;
               
               ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(ЭтотОбъект);
               …
              КонецПроцедуры

              \n

              7. Обработчики обновления, процедуры заполнения данных обновления и процедуры проверки рекомендуется располагать в модулях менеджера обновляемых объектов, а в качестве имен для них использовать следующие:

              \n

              • Обработчики обновления (Обработчик.Процедура) – ОбработатьДанныеДляПереходаНаНовуюВерсию.
              • Процедуры заполнения данных обновления (Обработчик.ПроцедураЗаполненияДанныхОбновления) – ЗарегистироватьДанныеКОбработкеДляПереходаНаНовуюВерсию.
              • Процедуры проверки (Обработчик.ПроцедураПроверки) – ДанныеОбновленыНаНовуюВерсиюПрограммы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "531", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Избыточное обращение внутри модуля через его имя или псевдоним ЭтотОбъект (к методу, свойству или реквизиту).", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "534", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Небезопасный запуск приложения.", +"Description": "

              Безопасность запуска приложений

              #std774

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При запуске внешней программы из кода требуется составлять строку запуска таким образом, чтобы она собиралась только из проверенных частей.
              Если одна из частей, из которых собирается строка запуска, содержит данные, полученные из базы данных, из поля ввода на форме или прочитаны из хранилища настроек, то перед запуском программы требуется проверить, являются ли запуск безопасным. Безопасными считаются такие строковые данные, которые не содержат в себе следующие символы: \"$\", \"`\", \"|\", \"||\" \";\", \"&\", \"&&\".

              \n

              Данное требование распространяется на все способы запуска программы, в том числе:

              \n
                \n
              • КомандаСистемы(<СтрокаКоманды>, <ТекущийКаталог>) \n
              • ЗапуститьПриложение(<СтрокаКоманды>, <ТекущийКаталог>, <ДождатьсяЗавершения>, <КодВозврата>) ; \n
              • НачатьЗапускПриложения(<ОписаниеОповещения>, <СтрокаКоманды>, <ТекущийКаталог>, <ДождатьсяЗавершения>); \n
              • ПерейтиПоНавигационнойСсылке(<НавигационнаяСсылка>); \n
              • Использование COM объектов \"Wscript.Shell\" и \"Shell.Application\".
              \n

              2. При использовании Библиотеки стандартных подсистем для запуска внешних программ требуется использовать следующий программный интерфейс:
              2.1. Для того чтобы открыть проводник с фокусировкой на указанном файле, использовать процедуру ФайловаяСистемаКлиент.ОткрытьПроводник.
              Например:

              // Для Windows
              ФайловаяСистемаКлиент.ОткрытьПроводник(\"C:\\Users\");
              ФайловаяСистемаКлиент.ОткрытьПроводник(\"C:\\Program Files\\1cv8\\common\\1cestart.exe\");
              // Для Linux
              ФайловаяСистемаКлиент.ОткрытьПроводник(\"/home/\");
              ФайловаяСистемаКлиент.ОткрытьПроводник(\"/opt/1C/v8.3/x86_64/1cv8c\");
              \n

              2.2. Для того чтобы открыть файл в программе просмотра, ассоциированной с расширением файла, использовать процедуру ФайловаяСистемаКлиент.ОткрытьФайл. Она исключает запуск исполняемых файлов (например, *.exe, *.bin, *.apk).
              Например:

              \n

              ФайловаяСистемаКлиент.ОткрытьФайл(КаталогДокументов() + \"test.pdf\");
              ФайловаяСистемаКлиент.ОткрытьФайл(\"D:\\test.xlsx\");

              \n

              2.3. Для того чтобы открыть веб-страницу в браузере, запустить программу по протоколу (например, mailto:, skype:, tel: и.т.д) или открыть навигационную ссылку информационной базы следует использовать процедуру ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку. При этом в веб-клиенте пользователю будет предложено установить расширение для работы с файлами в тех случаях, когда оно необходимо для выполнения операции.
              Например:

              \n

              ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(\"https://1c.ru\");
              ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(\"e1cib/navigationpoint/startpage\"); // начальная страница.
              ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(\"mailto:help@1c.ru\");
              ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(\"skype:echo123?call\");

              \n

              В то же время, для открытия проводника или файла в программе просмотра не следует формировать ссылку по протоколу file://, для этого следует использовать одну из процедур: ОткрытьПроводник (см. п. 2.1) или ОткрытьФайл (см. п. 2.2).

              \n

              2.4. Для того чтобы:

              \n
                \n
              • запускать файлы на исполнение (например, *.exe, *bat), \n
              • использовать системные команды (например, ping, tracert или traceroute, обращаться к rac-клиенту), \n
              • выполнять команды на сервере, \n
              • а также получать код возврата и значения потоков вывода (stdout) и ошибок (stderr)
              \n

              следует использовать ФайловаяСистемаКлиент.ЗапуститьПрограмму (в клиентском коде) и ФайловаяСистема.ЗапуститьПрограмму (в серверном коде).
              Например:

              \n

              ФайловаяСистемаКлиент.ЗапуститьПрограмму(\"calc\");

              \n

              Пример запуска с ожиданием завершения и получения кода возврата:

              \n

              ПараметрыЗапускаПрограммы = ФайловаяСистема.ПараметрыЗапускаПрограммы();
              ПараметрыЗапускаПрограммы.ДождатьсяЗавершения = Истина;
              ПараметрыЗапускаПрограммы.ПолучитьПотокВывода = Истина;
              ПараметрыЗапускаПрограммы.ПолучитьПотокОшибок = Истина;

              \n

              Результат = ФайловаяСистема.ЗапуститьПрограмму(
               \"ping 127.0.0.1 -n 5\", ПараметрыЗапускаПрограммы);

              \n

              КодВозврата = Результат.КодВозврата;
              ПотокВывода = Результат.ПотокВывода;
              ПотокОшибок = Результат.ПотокОшибок;

              \n

              3. Для выполнения команды, требующей запуск внешней программы в режиме наивысших прав (например, в ОС Windows - с отображением запроса повышения прав UAC), необходимо:

              \n
                \n
              • реализовывать ее на управляемой форме в виде кнопки или пункта меню; \n
              • а на самой кнопке, начинающей выполнение действия, отобразить значок щита (общая картинка ЗначокЩита из Библиотеки стандартных подсистем).
              \n

              \n

              \n

              См. например, требования для ОС Windows.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "536", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует отключение макросов при работе с документом Microsoft Word.", +"Description": "

              Безопасность программного обеспечения, вызываемого через открытые интерфейсы

              #std775

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При использовании интеграции со сторонними приложениями с помощью открытых интерфейсов (в частности, с помощью COM) требуется отключать исполнение произвольного кода средствами вызываемого приложения.

              \n

              2. В частности, перед программным открытием документов Microsoft Word и Microsoft Excel через COM следует запрещать исполнение макросов. Иначе это может привести к выполнению вредоносных макросов (вирусов), если таковые присутствуют в документе.

              \n

              НЕПРАВИЛЬНО открывать документ Microsoft Word по умолчанию:

              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              Документ = ОбъектWord.Documents.Open(ИмяФайла);
              ПРАВИЛЬНО открывать документ Microsoft Word с отключением макросов:
              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              ОбъектWord.WordBasic.DisableAutoMacros(1);
              Документ = ОбъектWord.Documents.Open(ИмяФайла);

              ПРАВИЛЬНО открывать документ Microsoft Excel с отключением макросов:

              ОбъектExcel = Новый COMОбъект(\"Excel.Application\");
              ОбъектExcel.AutomationSecurity = 3; // msoAutomationSecurityForceDisable = 3
              Документ = ОбъектExcel.Workbooks.Open(ИмяФайла);
              \n

              3. Если при программном открытии документов Microsoft Office все же необходимо разрешить выполнение автоматически запускающихся макросов, тогда следует реализовать следующую логику работы:

              \n
              \n

              • В конфигурации сделать формы настройки безопасности запуска макросов, отдельно для клиентского и серверного кода со следующими элементами:

              \n
              \n

              o «Запретить автоматический запуск»;

              \n

              o «Разрешить запуск подписанных макросов (рекомендуется)» (выбран по умолчанию);

              \n

              o «Разрешить запуск не подписанных макросов (опасно)».

              \n

              • Форма настройки для клиентского кода должна быть доступна каждому пользователю, настройки должны сохраняться в разрезе пользователей, каждому пользователью должны быть доступны только свои настройки.

              \n

              • Форма настройки для серверного кода должна быть доступна только администратору, доступ к настройкам должен быть только у администратора.

              \n

              • При программном открытии документов следует учитывать эти настройки.

              \n

              3.1. Проверку наличия подписи макросов в документах Microsoft Word можно реализовать так:

              \n

              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              ОбъектWord.WordBasic.DisableAutoMacros(1); // Отключить автозапуск
              Документ = ОбъектWord.Documents.Open(ФайлДокумента);

              \n

              Если Документ.VBASigned Тогда
               ОбъектWord.WordBasic.DisableAutoMacros(0); // Включить автозапуск
               Документ.RunAutoMacro(2); // wdAutoOpen = 2
              Иначе
               Документ.Close();
               ВызватьИсключение НСтр(\"ru = 'Документ не подписан. Открытие отменено.'\");
              КонецЕсли;

              \n

              3.2. Проверку наличия подписи макросов в документах Microsoft Excel можно реализовать так:

              \n

              ОбъектExcel = Новый COMОбъект(\"Excel.Application\");
              ИсходныйУровеньБезопасности = ОбъектExcel.AutomationSecurity;
              ОбъектExcel.AutomationSecurity = 3; // msoAutomationSecurityForceDisable = 3
              Документ = ОбъектExcel.Workbooks.Open(ФайлДокумента);
              ОбъектExcel.AutomationSecurity = ИсходныйУровеньБезопасности;

              \n

              Если Документ.VBASigned Тогда
               Документ.Close();
               Документ = ОбъектExcel.Workbooks.Open(ФайлДокумента);
              Иначе
               Документ.Close();
               ВызватьИсключение НСтр(\"ru = 'Документ не подписан. Открытие отменено.'\");
              КонецЕсли;

              \n

              См. также: О параметрах исполнения макросов в Microsoft Excel

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "537", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Отсутствует отключение макросов при работе с документом Microsoft Excel.", +"Description": "

              Безопасность программного обеспечения, вызываемого через открытые интерфейсы

              #std775

              Область применения: управляемое приложение, обычное приложение.

              \n

              1. При использовании интеграции со сторонними приложениями с помощью открытых интерфейсов (в частности, с помощью COM) требуется отключать исполнение произвольного кода средствами вызываемого приложения.

              \n

              2. В частности, перед программным открытием документов Microsoft Word и Microsoft Excel через COM следует запрещать исполнение макросов. Иначе это может привести к выполнению вредоносных макросов (вирусов), если таковые присутствуют в документе.

              \n

              НЕПРАВИЛЬНО открывать документ Microsoft Word по умолчанию:

              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              Документ = ОбъектWord.Documents.Open(ИмяФайла);
              ПРАВИЛЬНО открывать документ Microsoft Word с отключением макросов:
              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              ОбъектWord.WordBasic.DisableAutoMacros(1);
              Документ = ОбъектWord.Documents.Open(ИмяФайла);

              ПРАВИЛЬНО открывать документ Microsoft Excel с отключением макросов:

              ОбъектExcel = Новый COMОбъект(\"Excel.Application\");
              ОбъектExcel.AutomationSecurity = 3; // msoAutomationSecurityForceDisable = 3
              Документ = ОбъектExcel.Workbooks.Open(ИмяФайла);
              \n

              3. Если при программном открытии документов Microsoft Office все же необходимо разрешить выполнение автоматически запускающихся макросов, тогда следует реализовать следующую логику работы:

              \n
              \n

              • В конфигурации сделать формы настройки безопасности запуска макросов, отдельно для клиентского и серверного кода со следующими элементами:

              \n
              \n

              o «Запретить автоматический запуск»;

              \n

              o «Разрешить запуск подписанных макросов (рекомендуется)» (выбран по умолчанию);

              \n

              o «Разрешить запуск не подписанных макросов (опасно)».

              \n

              • Форма настройки для клиентского кода должна быть доступна каждому пользователю, настройки должны сохраняться в разрезе пользователей, каждому пользователью должны быть доступны только свои настройки.

              \n

              • Форма настройки для серверного кода должна быть доступна только администратору, доступ к настройкам должен быть только у администратора.

              \n

              • При программном открытии документов следует учитывать эти настройки.

              \n

              3.1. Проверку наличия подписи макросов в документах Microsoft Word можно реализовать так:

              \n

              ОбъектWord = Новый COMОбъект(\"Word.Application\");
              ОбъектWord.WordBasic.DisableAutoMacros(1); // Отключить автозапуск
              Документ = ОбъектWord.Documents.Open(ФайлДокумента);

              \n

              Если Документ.VBASigned Тогда
               ОбъектWord.WordBasic.DisableAutoMacros(0); // Включить автозапуск
               Документ.RunAutoMacro(2); // wdAutoOpen = 2
              Иначе
               Документ.Close();
               ВызватьИсключение НСтр(\"ru = 'Документ не подписан. Открытие отменено.'\");
              КонецЕсли;

              \n

              3.2. Проверку наличия подписи макросов в документах Microsoft Excel можно реализовать так:

              \n

              ОбъектExcel = Новый COMОбъект(\"Excel.Application\");
              ИсходныйУровеньБезопасности = ОбъектExcel.AutomationSecurity;
              ОбъектExcel.AutomationSecurity = 3; // msoAutomationSecurityForceDisable = 3
              Документ = ОбъектExcel.Workbooks.Open(ФайлДокумента);
              ОбъектExcel.AutomationSecurity = ИсходныйУровеньБезопасности;

              \n

              Если Документ.VBASigned Тогда
               Документ.Close();
               Документ = ОбъектExcel.Workbooks.Open(ФайлДокумента);
              Иначе
               Документ.Close();
               ВызватьИсключение НСтр(\"ru = 'Документ не подписан. Открытие отменено.'\");
              КонецЕсли;

              \n

              См. также: О параметрах исполнения макросов в Microsoft Excel

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "538", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Объект, не имеющий визуального представления, входит в состав подсистемы, включенной в командный интерфейс.", +"Description": "

              Использование подсистем

              #std543

              Область применения: управляемое приложение, обычное приложение.

              \n

              Методическая рекомендация (полезный совет)

              \n

              1.1. С помощью подсистем решаются две методические задачи:

              \n
                \n
              • \n
                Сформировать глобальный командный интерфейс основного окна приложения, которое дает пользователю представление о функциональности приложения в целом.
                \n
              • \n
                Сгруппировать объекты метаданных по функциональному признаку для удобства разработки.
              \n

              В простейшем случае, получившаяся для обоих задач структура подсистем конфигурации может совпадать.

              \n

              \n

              Например, видимые для пользователей разделы командного интерфейса «Закупки», «Продажи» и пр. могут использоваться одновременно и при разработке: для быстрого отбора объектов в окне метаданных Конфигуратора, при переносе объектов в другие конфигурации, для задания ограничений области поиска при глобальном поиске по конфигурации и т.д.

              \n

              У таких подсистем должен быть установлен флажок Включать в командный интерфейс.

              \n

              1.2. В общем случае, подсистема, логически объединяющая некоторый набор объектов метаданных, может не совпадать с одним разделом командного интерфейса приложения. Для логического объединения набора объектов метаданных по функциональному признаку рекомендуется заводить в конфигурации отдельную иерархию подсистем, не включенных в командный интерфейс. У таких «функциональных» подсистем флажок Включать в командный интерфейс должен быть снят.

              \n

              Примеры:

              \n
                \n
              • \n
                справочник Номенклатура логически относится к одной «функциональной» подсистеме «Нормативно-справочная информация», но доступен в командном интерфейсе одновременно в двух разделах – «Нормативно-справочная информация» и «Маркетинг»
                \n
              • \n
                в раздел командного интерфейса «Настройка и администрирование» помещаются команды открытия списков объектов, логически относящихся к тем «функциональным» подсистемам конфигурации, которые предоставляют возможность настройки для администратора системы.
              \n

              1.3. При этом, общие модули, регламентные задания, константы, подписки на события и прочие объекты, не имеющие визуального представления в командном интерфейсе, рекомендуется включать только в состав «функциональных» подсистем.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "540", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL.", +"Description": "

              Упорядочивание результатов запроса

              #std412

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Если алгоритм обработки результатов запроса зависит от порядка записей в запросе или если результат обработки запроса в той или иной форме представляется пользователю, то в тексте запроса следует использовать предложение УПОРЯДОЧИТЬ ПО. В отсутствие выражения УПОРЯДОЧИТЬ ПО невозможно сделать никаких предположений о том, в каком порядке будут представлены записи в результатах запроса.

              \n

              Типичные примеры проблем, которые могут возникать (даже при работе на одной и той же СУБД в непредсказуемые моменты времени):

              \n
                \n
              • разная последовательность строк табличной части при заполнении по результатам запроса; \n
              • разный порядок вывода данных (строк, колонок) в отчетах; \n
              • разное заполнение движений документа по результатам запроса (*).
              \n

              Вероятность возникновения разных результатов при выполнении одинаковых действий повышается 

              \n
                \n
              • при переносе информационной базы на другую СУБД \n
              • при смене версии СУБД \n
              • при изменении параметров СУБД
              \n

              * Примечание: упорядочивание результатов запросов, по которым формируются движения, оправдано только в том случае, если упорядочивание является частью алгоритма формирования движений (например, списание остатков партий товаров по FIFO). В остальных случаях упорядочивать записи не следует, так как дополнительное упорядочивание будет создавать избыточную нагрузку на СУБД.

              \n

              1.2. При сортировке по полю запроса, которое может потенциально содержать NULL, следует учитывать, что в разных СУБД порядок сортировки по этому полю может отличаться.

              \n

              Неправильно:

              \n

              ВЫБРАТЬ
                СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
                ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
              ИЗ
                Справочник.Номенклатура КАК СправочникНоменклатура
                  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК ЗапасыОстатки
                  ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)

              \n

              УПОРЯДОЧИТЬ ПО
                КоличествоОстаток

              \n

              Правильно:

              \n

              ВЫБРАТЬ
                СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
                ЕСТЬNULL(ЗапасыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
              ИЗ
                Справочник.Номенклатура КАК СправочникНоменклатура
                  ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК ЗапасыОстатки
                  ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)

              \n

              УПОРЯДОЧИТЬ ПО
                КоличествоОстаток

              \n
              \n

              См. также: Особенности работы с различными СУБД

              \n

              1.3. Если результаты запроса должны тем или иным образом отображаться пользователю, то

              \n
                \n
              • упорядочивать результаты таких запросов необходимо по полям примитивных типов; \n
              • упорядочивание по полям ссылочных типов нужно заменять на упорядочивание по строковым представлениям этих полей.
              \n

              В противном случае порядок следования строк будет выглядеть для пользователя случайным (необъяснимым).

              \n
              \n

              См. также: Сортировка строк таблиц значений

              \n

              1.4. Отсутствие предложения УПОРЯДОЧИТЬ ПО оправдано только в тех случаях, когда

              \n
                \n
              • алгоритм обработки результатов запроса не рассчитывает на определенный порядок записей \n
              • результат обработки выполненного запроса не показывается пользователю \n
              • результат запроса - заведомо одна запись
              \n

              В таких случаях рекомендуется не добавлять предложение УПОРЯДОЧИТЬ ПО в текст запроса, так как это приводит к дополнительным затратам времени при выполнении запроса.

              \n

              Совместное использование с конструкцией РАЗЛИЧНЫЕ

              \n

              2. Если в запросе используется конструкция РАЗЛИЧНЫЕ, упорядочивание следует выполнять только по полям, включенным в выборку (в секции ВЫБРАТЬ). 

              Данное требование связано со следующей особенностью выполнения запросов: в поля выборки неявно включаются поля упорядочивания, что в свою очередь может привести к появлению в результате запроса нескольких строк с одинаковыми значениями полей выборки. 

              \n

              Ограничения на использование конструкции АВТОУПОРЯДОЧИВАНИЕ

              \n

              3. Использование конструкции ПЕРВЫЕ совместно с конструкцией АВТОУПОРЯДОЧИВАНИЕ запрещено.

              \n

              В остальных случаях конструкцию АВТОУПОРЯДОЧИВАНИЕ также не рекомендуется использовать, так как разработчик не контролирует, какие именно поля будут использованы для упорядочивания. Применение такой конструкции оправдано только в тех случаях, когда получаемый порядок записей не важен, но при этом он должен быть одинаковым в не зависимости от применяемой СУБД. 

              \n

              Причины использования конструкции АВТОУПОРЯДОЧИВАНИЕ следует указывать в комментарии, размещенном непосредственно перед текстом запроса.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "541", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неверно установлены права базовой роли на объект метаданных.", +"Description": "

              Настройка ролей и прав доступа

              #std689

              Область применения: управляемое приложение, обычное приложение.

              \n
              \n

              Действует для конфигураций УП (ERP), УТ 11 и входящих в них библиотек.
              Для других конфигураций рекомендуется к использованию.
              Содержит уточнения к требованиям других стандартов.

              \n

              1. Общие положения

              \n
              \n

              1.1. Роли создаются «атомарными», т.е. дающими права на доступ к элементарным функциям программы. Из этих элементарных ролей создаются профили пользователей, которые уже и назначаются пользователям средствами БСП. Деление прав на доступ к объектам между функциями должно быть таким, чтобы на типовом внедрении не возникало необходимости в создании новых ролей.

              \n

              Исключение: для ролей, назначаемых внешним пользователям, задается исчерпывающий набор прав к необходимым объектам.

              \n

              Например, в УП(ERP) это роль ПартнерСамообслуживание.

              \n

              1.2. Роль ПолныеПрава (англ. FullAccess) совместно с ролью АдминистраторСистемы (англ. SystemAdministrator) дает неограниченный доступ (без RLS) ко всем объектам. См. стандартные роли.

              \n

              1.3. Ни одна роль (в т.ч. ПолныеПрава и АдминистраторСистемы) не должна давать право на интерактивное удаление ссылочных объектов.

              \n
                \n
              • после создания нового объекта нужно зайти в роль ПолныеПрава и отключить право интерактивного удаления у ссылочных объектов.
              \n

              1.4. Только роль ПолныеПрава и АдминистраторСистемы должна давать право на удаление ссылочных объектов.

              \n

              1.5. Только для роли ПолныеПрава должен быть установлен флаг «Устанавливать права для новых объектов». Для всех остальных ролей этот флаг должен быть снят.

              \n

              1.6. Если какое-то право может быть использовано только администратором системы (например, использование какого-то отчета или обработки), то достаточно, чтобы это предоставлялось одной из ролей ПолныеПрава и АдминистраторСистемы, создавать отдельные роли в этом случае не требуется.

              \n

              1.7. Во всех документах, предполагающих проведение, должны быть выставлены флаги «Привилегированный режим при проведении» и «Привилегированный режим при отмене проведения», поэтому не нужно создавать роли, дающие права на изменение регистров, подчиненных регистраторам.

              \n

              Исключение: документы, предназначенные для непосредственной корректировки записей регистров, могут проводиться с проверкой прав доступа, но в этом случае необходимо предусмотреть роли, дающие права на изменение регистров.

              \n

              1.8. Во всех функциональных опциях должны быть выставлены флаги «Привилегированный режим при получении».

              \n

              Исключение: в конфигурации могут быть предусмотрены параметризированные ФО, для которых разработчик специально предусматривает различия в получаемых значениях пользователями с разными правами.
              Пример: Есть параметризованная ФО ИспользоватьВалютуПриРасчетеСПерсоналом, которая параметризуется организацией. Если пользователь будет получать ее значение в контексте своих прав, то он не увидит поле «валюта» в документе, если у него нет ни одной организации, где применяется валютный учет.

              \n

              1.9. Не должно быть ролей, кроме стандартных ролей БСП, которые дают общие права (такие как Администрирование, ТонкийКлиент и т.п.).

              \n
                \n
              • при создании новой роли нужно следить, чтобы эти права были выключены.
              \n

              1.10. В отдельных случаях для неконфиденциальных данных и общедоступных функций не требуется создавать отдельную роль на чтение (а также просмотр и ввод по строке - для ссылочных данных), а следует включать эти права в роли БазовыеПрава<ИмяБиблиотеки> (англ. BasicAccess<LibraryName>) и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки> (англ. BasicAccessExternalUser<LibraryName>)  (эта роль необходима только если в конфигурации предусмотрена работа с внешними пользователями). Например, это константы, общенациональные классификаторы, общие формы выбора периода, ввода контактной информации и др.

              \n

              1.11. Не допускается, чтобы одна роль давала права на объекты, которые относятся к другим подсистемам
              Например, в хранилище УП (ERP) нельзя, чтобы одна роль давала права на объекты, которые есть в УТ 11 и на объекты, которых в УТ 11 нет. См. также: Разработка ролей в библиотеках.

              \n

              2. Правила создания ролей к элементарным функциям

              \n

              2.1.  Объекты, при проектировании прав доступа, необходимо объединить в элементарные функции. Если объекты входят в одну функцию, то это означает, что не может быть задачи, когда доступ к этим объектам может быть разный.

              \n

              Пример:
              Есть документ «Заказ клиента» и связанный с ним регистр накопления «Заказы клиентов», который хранит остатки неотгруженных товаров и неоплаченных сумм. По сути этот регистр является отражением текущего состояния табличной части заказа. Если пользователь имеет права на документ, то будет странно, что он не будет иметь прав на регистр. Поэтому документ «Заказ клиента» и регистр накопления «Заказы клиентов» можно объединить в одну элементарную функцию. Если есть отчет, отображающий в удобном виде остатки регистра «Заказы клиентов», то логично его тоже включить в эту функцию.

              \n

              Противоположный пример:
              Есть документ «Реализация товаров и услуг», выступающий в роли распоряжения на отгрузку товаров. Остатки по распоряжениям на отгрузку товаров хранит регистр накопления «Товары к отгрузке». Объединять «Реализацию товаров и услуг» и регистр «Товары к отгрузке» в рамках одной функции было бы не правильно, т.к., например, кладовщик, вполне может иметь права на чтение регистра «Товары к отгрузке», но может не иметь прав на чтение документа «Реализация товаров и услуг».

              \n

              2.2. В случае если возникают сомнения в том, что два объекта могут быть отнесены к одной элементарной функции, лучше выделить их в разные.

              \n

              2.3. Каждый объект должен быть отнесен к элементарной функции, и только к одной.

              \n

              2.4. Объекты, относящиеся к разным библиотекам не могут быть отнесены к одной элементарной функции.

              \n

              3. Ссылочные объекты и регистры

              \n

              3.1. Для функций, включающих в себя ссылочные объекты и независимые регистры сведений, должно быть создано две роли

              \n
                \n
              • Чтение<ИмяФункции> (англ. Read<FeatureName>); \n
              • ДобавлениеИзменение<ИмяФункции> (англ. InsertUpdate<FeatureName>)  (или Изменение<ИмяФункции> (англ. Update<FeatureName>), если добавление выполняется автоматически, либо только администратором).
              \n

              Роли должны содержать следующие права (когда они имеются у объекта метаданных):

              \n
                \n
              • \n
                Чтение<ИмяФункции> содержит права:
                \n
                  \n
                • \n
                  Чтение, Просмотр, Ввод по строке.
                \n
              • \n
                Изменение<ИмяФункции> содержит те же права, что и роль Чтение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Изменение, Редактирование;
                  \n
                • \n
                  Проведение, Отмена проведения, Интерактивное проведение, Интерактивная отмена проведения, Интерактивное изменение проведенных (для документов);
                  \n
                • \n
                  Управление итогами (для регистров).
                \n
              • \n
                ДобавлениеИзменение<ИмяФункции> содержит те же права, что и роль Изменение<ИмяФункции>, а также:
                \n
                  \n
                • \n
                  Добавление, Интерактивное добавление;
                  \n
                • \n
                  Интерактивная пометка удаления, Интерактивное снятие пометки удаления.
              \n

              3.2. Необходимо помнить, что для регистров, подчиненных регистратору, обычно не требуется назначать права на изменение (см. п. 1.7).

              \n

              4. Журналы документов

              \n

              4.1. Если все документы, входящие в журнал, отнесены к одной элементарной функции, то права на чтение и просмотр журнала нужно включить во все роли этой функции.

              4.2. Платформа 1С:Предприятие имеет следующую особенность: если у пользователя нет прав на чтение любого документа, входящего в журнал документов, то платформа не дает доступ ко всем графам журнала, в котором отражается этот документ, для всех документов, входящих в журнал. Поэтому нет никакого практического смысла создавать отдельную роль для доступа к журналу: журнал может входить в элементарную функцию, или может быть доступен только пользователю с полными правами.

              \n

              5. Константы

              \n

              5.1.  Если предполагается, что константа должна изменяться только администратором системы, то права на изменение и редактирование должны быть только у одной из ролей: ПолныеПрава или АдминистраторСистемы. Эти роли должны включать также и права на чтение и просмотр констант.

              \n

              5.2.  Если предполагается, что константу может менять пользователь, то нужно включить права на чтение, просмотр, изменение и редактирование в уже имеющуюся «настроечную» роль или создать отдельную роль Изменение<ИмяКонстанты> (англ. Update<ConstantName>), дающую права на чтение, просмотр, изменение и редактирование этой константы.

              \n

              5.3.  В подавляющем большинстве случаев константа используется для хранения неконфиденциальной информации, поэтому права на чтение и просмотр константы нужно назначать роли БазовыеПрава<ИмяБиблиотеки> и БазовыеПраваВнешнихПользователей<ИмяБиблиотеки>. Это позволяет избежать неоправданной установки привилегированного режима при чтении значения константы из кода.

              \n

              5.4. В редких случаях, когда константа используется для хранения конфиденциальной информации, необходимо создать роль Чтение<ИмяКонстанты> (англ. Read<ConstantName>). При этом, если значение должно быть доступно только администратору, создавать отдельную роль на чтение не требуется.

              \n

              Например, для константы ПараметрыАдминистрированияИБ создавать отдельную роль на чтение не требуется – достаточно включения прав на чтение и просмотр в роль АдминистраторСистемы.

              \n

              6. Подсистемы, отображаемые в главном командном интерфейсе

              \n

              6.1.  Для каждой подсистемы верхнего уровня должна быть создана роль Подсистема<ИмяПодсистемы> (англ. Subsystem<SubsystemName>), дающая право на просмотр

              \n

              6.2.  Если интерфейс подсистемы организован так, что часть настроек и справочников отображаются в отдельной форме, то роль, дающая право на подсистему, должна включать права на просмотр этой формы (например, в УП(ERP) часть справочников в разделах командного интерфейса не вынесены и отображаются в форме, вызываемой командой «Настройки и справочники»).

              \n

              7. Отчеты

              \n

              7.1. Если отчет строится на основе данных, входящих в одну элементарную функцию (п. 2.1), то в общем случае права на доступ к такому отчету можно включить в роли, созданные по этой элементарной функции.

              \n

              Пример:
              Отчет по исполнению заказов клиентов полностью строится на основе данных регистр накопления ЗаказыКлиентов, поэтому права на отчет нужно включить в роль, дающую право на чтение регистра.

              \n

              7.2. Если на внедрении могут возникнуть задачи отдельной настройки прав к отчету, который строится на основе данных, входящих в одну элементарную функцию, то для доступа к такому отчету необходимо создать отдельную роль ПросмотрОтчета<ИмяОтчета> (англ. ViewReport<ReportName>), дающую права использования и просмотра.

              \n

              Пример:
              Хотя отчет по контактной информации отображает данные входящие в элементарную функцию информации о клиентах, но на внедрении может потребоваться ограничить доступ к отчету, который позволяет вывести информацию по всем клиентам сразу.

              \n

              7.3. Если отчет строится на основе данных, входящих в несколько элементарных функций,  необходимо создать роль ПросмотрОтчета<ИмяОтчета>, дающую права использования и просмотра.

              \n

              Пример:
              Отчет по выполнению плана продаж строится на основе данных о планах и данных о продажах. Права чтение этих данных дают роли, относящиеся к разным элементарным функциям. Для реализации доступа к отчету нужно создать отдельную роль.

              \n

              7.4. Однотипные отчеты при проектировании прав доступа можно объединить в элементарные функции при соблюдении следующих условий:

              \n
                \n
              • отчеты не входят в другие элементарные функции (см. п. 7.1); \n
              • на внедрении не может возникнуть задачи различной настройки прав доступа к этим отчетам.
              \n

              8. Обработки и общие формы

              \n

              8.1. Для каждой обработки, представляющей из себя рабочее место, т.е. в ГКИ есть отдельная команда для открытия этой обработки, должна быть создана роль ИспользованиеОбработки<ИмяОбработки> (англ. Use DataProcessor<DataProcessorName>), дающая права на просмотр и использование.

              \n

              При этом не допускается объединять права доступа к разным обработкам-рабочим местам в одной роли.

              \n

              8.2.  Права ко всем другим типам обработок, например

              \n
                \n
              • вспомогательные обработки, которые нельзя вызвать из глобального командного интерфейса, а можно открыть только из других объектов, например, подбор товаров; \n
              • обработки, в которых расположен общий код, например, код формирования печатных форм;
              \n

              должны быть назначены в роли БазовыеПрава<ИмяБиблиотеки>.

              \n

              8.3. Права к обработкам, предназначенным исключительно для администратора программы, нужно назначать только роли ПолныеПрава, не создавая отдельных ролей для таких обработок.

              8.4. Все эти правила равным образом применяются для общих форм. Название роли для общей формы, описанной в п. 8.1. – ИспользованиеОбщейФормы<ИмяОбщейФормы> (англ. UseCommonForm<CommonFormName>).

              8.5 Исключения из этих правил описаны в п. 6.2

              Пример:
              В УТ 11 права к обработкам ПодборТоваров и ПоискОбъектовПоШтрихкоду назначены роли БазовыеПраваУТ.

              \n

              9. Команды

              \n

              9.1.  Если команда не предполагает изменение данных, то в общем случае право на просмотр должно быть назначено той роли, которая дает право на просмотр объекта.

              \n
                \n
              • т.к. роль, дающая право на изменение объекта дает также права на чтение объекта, нужно не забывать проставлять права на команду и в роли с правом на чтение, и в роли с правом на изменение; \n
              • права на команды печати, которые расположены в обработках (это печатные формы, которые печатаются из нескольких объектов) нужно назначать роли БазовыеПрава<ИмяБиблиотеки>
              \n

              9.2.  Если команда связана с изменением данных, то право на просмотр нужно назначить роли, которая дает права на изменение объектов.

              \n

              10. Права, не связанные с доступом к объектам

              \n

              10.1. В случае если возникает необходимость давать пользователям какие-то дополнительные права, не связанные с доступом к объектам, нужно создавать роль <НаименованиеПрава>, не дающую доступ ни к одному объекту. При этом в наименовании не нужно использовать слово «Право».

              \n

              Пример:
              Правильно ОтклонениеОтУсловийЗакупок
              Неправильно ПравоСозданияВыпускПродукцииБезЗаказа

              \n

              10.2. В коде конфигурации нужно проверять наличие у пользователя этой роли. Пользователь с ролью ПолныеПрава должен проходить проверку без необходимости включения в его профиль этой роли. Для проверки следует использовать функцию БСП Пользователи.РолиДоступны.

              \n

              10.3. Использование других механизмов, кроме проверки наличия роли (или какого-то права) при реализации дополнительных прав пользователя, не допускается.

              \n

              11. Права для внешних пользователей

              \n

              Роли, предназначенные исключительно для предоставления прав доступа внешним пользователям (представленным в программе одним из объектов, например, элементами справочников Сотрудники, Партнеры, Физические лица и др.), следует называть с определенным префиксом.
              Например, префикс Самообслуживание для доступа к рабочему месту по самообслуживанию клиентов в торговом решении:

              \n
                \n
              • СамообслуживаниеОформлениеПретензий, синоним Самообслуживание: оформление претензий \n
              • СамообслуживаниеПросмотрОтчетаСостояниеВыполненияЗаказа, синоним Самообслуживание: просмотр отчета «Состояние выполнения заказа» \n
              • СамообслуживаниеДобавлениеИзменениеКонтрагентов, синоним Самообслуживание: добавление и изменение контрагентов
              \n

              12. Права к устаревшим объектам

              \n

              Устаревшие объекты метаданных с префиксом Удалить должны быть исключены из всех ролей, кроме ролей ПолныеПрава или АдминистраторСистемы.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "543", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В отложенном обработчике обновления не указан идентификатор.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
              \n

              Отложенное обновление данных

              \n

              Область применения: управляемое приложение, обычное приложение.

              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
              Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

              \n

              1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

              \n

              Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

              \n

              Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
              • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
              \n

              Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

              \n

              2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

              \n

              В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

              \n

              3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

              \n

              В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

              \n

              Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

              \n

              Например:

              \n

              Обработчик = Обработчикиобавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

              \n

              4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
              что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
              Например:

              \n
                \n
              • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
              • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
              • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
              • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
              \n

              5. Синтаксис процедуры-обработчика отложенного обновления:

              \n

              Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

              \n

              где Параметры – Структура со свойствами:

              \n
                \n
              • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
              • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
                  \n
                • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
                • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
              \n

              (*) Примечание: актуально для версий БСП 2.3.1 и выше.

              \n

              6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
              Также рекомендуется начинать обработку с самых \"свежих\" данных.
              Например:

              \n

               Запрос = Новый Запрос;
               Запросекст = 
               \"ВЫБРАТЬ ПЕРВЫЕ 1000
               | ЗаказПокупателясылка
               |ИЗ
               | Документ.ЗаказПокупателя КАК ЗаказПокупателя
               |ГДЕ
               | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
               |
               |УПОРЯДОЧИТЬ ПО
               | ЗаказПокупателя.Дата УБЫВ\";

              \n

              7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

              \n

               ПараметрыбработкаЗавершена = Ложь;
               
               ПроблемныхОбъектов = 0;
               ОбъектовОбработано = 0;
               
               Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
                
                Попытка
                 
                 ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
                 ОбъектовОбработано = ОбъектовОбработано + 1;
                 
                Исключение
                 // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
                 ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
                 
                 ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
                  НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
                   |%2'\"), 
                   ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
                 ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
                  Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
                КонецПопытки;
                
               КонецЦикла;
               
               Если ОбъектовОбработано = 0 Тогда
                ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                 НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
                  ПроблемныхОбъектов);
                ВызватьИсключение ТекстСообщения;
               Иначе
                ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
                 Метаданные.Документы._ДемоЗаказПокупателя,,
                  НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
               КонецЕсли;

              \n

              При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

              \n

              8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

              \n

              Например:

              \n

              Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

               НачатьТранзакцию();
               Попытка
               
                Блокировка = Новый БлокировкаДанных;
                ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
                ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
                Блокировка.Заблокировать();
                
                ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

              \n

                // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
                Если ДокументОбъект = Неопределено Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                
                // Обрабатываем документ
                // ...
                
                ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
                
                ЗафиксироватьТранзакцию();
               Исключение
                ОтменитьТранзакцию();
                ВызватьИсключение;
               КонецПопытки;

              \n

              КонецПроцедуры

              \n

              9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

              \n

              10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

              \n
                \n
              • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
              • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
              \n

              В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

              \n

              11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

              \n

              С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

              \n

              Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

              \n

              Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "544", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В отложенном обработчике обновления не указан комментарий.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
              \n

              Отложенное обновление данных

              \n

              Область применения: управляемое приложение, обычное приложение.

              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
              Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

              \n

              1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

              \n

              Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

              \n

              Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
              • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
              \n

              Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

              \n

              2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

              \n

              В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

              \n

              3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

              \n

              В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

              \n

              Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

              \n

              Например:

              \n

              Обработчик = Обработчикиобавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

              \n

              4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
              что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
              Например:

              \n
                \n
              • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
              • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
              • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
              • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
              \n

              5. Синтаксис процедуры-обработчика отложенного обновления:

              \n

              Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

              \n

              где Параметры – Структура со свойствами:

              \n
                \n
              • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
              • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
                  \n
                • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
                • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
              \n

              (*) Примечание: актуально для версий БСП 2.3.1 и выше.

              \n

              6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
              Также рекомендуется начинать обработку с самых \"свежих\" данных.
              Например:

              \n

               Запрос = Новый Запрос;
               Запросекст = 
               \"ВЫБРАТЬ ПЕРВЫЕ 1000
               | ЗаказПокупателясылка
               |ИЗ
               | Документ.ЗаказПокупателя КАК ЗаказПокупателя
               |ГДЕ
               | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
               |
               |УПОРЯДОЧИТЬ ПО
               | ЗаказПокупателя.Дата УБЫВ\";

              \n

              7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

              \n

               ПараметрыбработкаЗавершена = Ложь;
               
               ПроблемныхОбъектов = 0;
               ОбъектовОбработано = 0;
               
               Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
                
                Попытка
                 
                 ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
                 ОбъектовОбработано = ОбъектовОбработано + 1;
                 
                Исключение
                 // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
                 ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
                 
                 ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
                  НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
                   |%2'\"), 
                   ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
                 ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
                  Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
                КонецПопытки;
                
               КонецЦикла;
               
               Если ОбъектовОбработано = 0 Тогда
                ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                 НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
                  ПроблемныхОбъектов);
                ВызватьИсключение ТекстСообщения;
               Иначе
                ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
                 Метаданные.Документы._ДемоЗаказПокупателя,,
                  НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
               КонецЕсли;

              \n

              При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

              \n

              8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

              \n

              Например:

              \n

              Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

               НачатьТранзакцию();
               Попытка
               
                Блокировка = Новый БлокировкаДанных;
                ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
                ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
                Блокировка.Заблокировать();
                
                ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

              \n

                // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
                Если ДокументОбъект = Неопределено Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                
                // Обрабатываем документ
                // ...
                
                ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
                
                ЗафиксироватьТранзакцию();
               Исключение
                ОтменитьТранзакцию();
                ВызватьИсключение;
               КонецПопытки;

              \n

              КонецПроцедуры

              \n

              9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

              \n

              10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

              \n
                \n
              • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
              • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
              \n

              В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

              \n

              11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

              \n

              С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

              \n

              Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

              \n

              Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "545", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В отложенном обработчике обновления обнаружен неуникальный идентификатор.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
              \n

              Отложенное обновление данных

              \n

              Область применения: управляемое приложение, обычное приложение.

              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
              Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

              \n

              1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

              \n

              Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

              \n

              Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
              • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
              \n

              Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

              \n

              2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

              \n

              В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

              \n

              3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

              \n

              В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

              \n

              Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

              \n

              Например:

              \n

              Обработчик = Обработчикиобавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

              \n

              4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
              что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
              Например:

              \n
                \n
              • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
              • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
              • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
              • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
              \n

              5. Синтаксис процедуры-обработчика отложенного обновления:

              \n

              Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

              \n

              где Параметры – Структура со свойствами:

              \n
                \n
              • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
              • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
                  \n
                • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
                • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
              \n

              (*) Примечание: актуально для версий БСП 2.3.1 и выше.

              \n

              6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
              Также рекомендуется начинать обработку с самых \"свежих\" данных.
              Например:

              \n

               Запрос = Новый Запрос;
               Запросекст = 
               \"ВЫБРАТЬ ПЕРВЫЕ 1000
               | ЗаказПокупателясылка
               |ИЗ
               | Документ.ЗаказПокупателя КАК ЗаказПокупателя
               |ГДЕ
               | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
               |
               |УПОРЯДОЧИТЬ ПО
               | ЗаказПокупателя.Дата УБЫВ\";

              \n

              7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

              \n

               ПараметрыбработкаЗавершена = Ложь;
               
               ПроблемныхОбъектов = 0;
               ОбъектовОбработано = 0;
               
               Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
                
                Попытка
                 
                 ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
                 ОбъектовОбработано = ОбъектовОбработано + 1;
                 
                Исключение
                 // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
                 ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
                 
                 ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
                  НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
                   |%2'\"), 
                   ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
                 ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
                  Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
                КонецПопытки;
                
               КонецЦикла;
               
               Если ОбъектовОбработано = 0 Тогда
                ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                 НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
                  ПроблемныхОбъектов);
                ВызватьИсключение ТекстСообщения;
               Иначе
                ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
                 Метаданные.Документы._ДемоЗаказПокупателя,,
                  НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
               КонецЕсли;

              \n

              При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

              \n

              8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

              \n

              Например:

              \n

              Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

               НачатьТранзакцию();
               Попытка
               
                Блокировка = Новый БлокировкаДанных;
                ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
                ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
                Блокировка.Заблокировать();
                
                ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

              \n

                // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
                Если ДокументОбъект = Неопределено Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                
                // Обрабатываем документ
                // ...
                
                ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
                
                ЗафиксироватьТранзакцию();
               Исключение
                ОтменитьТранзакцию();
                ВызватьИсключение;
               КонецПопытки;

              \n

              КонецПроцедуры

              \n

              9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

              \n

              10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

              \n
                \n
              • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
              • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
              \n

              В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

              \n

              11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

              \n

              С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

              \n

              Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

              \n

              Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "546", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "В отложенном обработчике обновления обнаружен неуникальный комментарий.", +"Description": "lang=RU style=\"tab-interval: 35.4pt\" link=blue vLink=purple>\n
              \n

              Отложенное обновление данных

              \n

              Область применения: управляемое приложение, обычное приложение.

              \n

              Действует для конфигураций на базе Библиотеки стандартных подсистем.
              Содержит уточнения к требованиям других стандартов.
              См. документацию к подсистеме \"Обновление версии ИБ\" на ИТС. 
              Для БСП версии 2.1.2 и более ранних см. Обработчики обновления информационной базы (БСП 2.1.2 и ранее)

              \n

              1. В тех случаях, когда исчерпаны все остальные средства по оптимизации обработчиков обновления, и можно выделить некоторые действия по обработке данных, выполнение которых не требуется обязательно для начала работы пользователей с программой, рекомендуется перенести эту обработку на более поздний момент времени и выполнять ее отложенно.

              \n

              Отложенная обработка данных не блокирует вход пользователей в программу и позволяет избежать ситуаций, когда обновление больших баз занимает существенное время (сутки и более), что нарушает график работы компании (из-за большого времени простоя информационной системы).

              \n

              Механизм отложенной обработки данных имеет два режима выполнения, которые настраиваются отдельно для каждой библиотеки и основной конфигурации:

              \n
                \n
              • Последовательно (по умолчанию) – отложенные обработчики обновления выполняются последовательно в интервале от номера версии информационной базы до номера версии конфигурации включительно (по возрастанию номеров версий, которые указаны в обработчиках). До тех пор пока один из обработчиков не завершил обработку своей порции данных, следующий не запускается. Данный режим обновления подходит для конфигураций (и библиотек), в которых отложенные обработчики для новых версий обрабатывают те же данные, что обрабатывали обработчики более старых версий. Кроме того, за счет последовательного выполнения к ним предъявляются минимальные требования по «устойчивости» к обрабатываемым данным: при обновлении «через» несколько версий они гарантированно могут рассчитывать на определенное начальное состояние обрабатываемых данных, которое осталось после выполнения обработчиков предыдущей версии. \n
              • Параллельно – отложенный обработчик после обработки первой порции данных передает управление следующему обработчику, а после выполнения последнего обработчика цикл повторяется заново, пока все данные не будут обработаны. Таким образом, более равномерно обновляются объекты информационной базы сразу всех типов, в отличие от последовательного режима, при котором объекты разных типов обрабатываются по очереди и многократно (при обновлении «через» несколько версий). Параллельный режим выполнения отложенных обработчиков целесообразно использовать в тех конфигурациях, большая часть данных которых обрабатывается отложенно. Подробнее см. Параллельный режим отложенного обновления.
              \n

              Примечание: отложенная обработка данных возможна только в клиент-серверном варианте работы. В файловом режиме работы отложенные обработчики обновления выполняются сразу, до начала работы пользователей с новой версией программы.

              \n

              2. Рекомендуется реализовать отложенные обработчики обновления для обработки больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, закрытых договоров, различных данных, отключенных в данный момент функциональными опциями и т.п.

              \n

              В большинстве случаев, отложенно следует обновлять документы, регистры, бизнес-процессы и задачи, которые имеют тенденцию накапливаться со временем.

              \n

              3. Для того чтобы указать, что обработчик обновления должен выполняться отложенно, необходимо свойству РежимВыполнения присвоить значение Отложенно, указать уникальный Идентификатор (*) и задать комментарий, который кратко поясняет пользователю, какие данные и как он обрабатывает, а также масштаб временно неработоспособного функционала.

              \n

              В свойстве Идентификатор указывается уникальный идентификатор отложенного обработчика обновления (УникальныйИдентификатор), который позволяет избежать ошибок при обновлении, если обработчик не успел завершить обработку данных, а в новой версии был переименован или перемещен в другой модуль. В таких случаях по идентификатору будет определен новый путь к обработчику, и он успешно завершит обработку данных.

              \n

              Для автоматической расстановки идентификаторов тем отложенным обработчикам, у которых ранее он не был задан, можно воспользоваться приложенной обработкой. (*)

              \n

              Например:

              \n

              Обработчик = Обработчикиобавить();
              Обработчик.Версия = \"1.2.3.4\";
              Обработчик.Процедура = \"Заказы.ЗаполнитьСтатусЗаказовПокупателей\";
              Обработчик.РежимВыполнения = \"Отложенно\";
              Обработчик.Идентификатор = Новый УникальныйИдентификатор(\"83d5c5dd-1462-4d72-ab98-f8f5dcc0664d\");
              Обработчик.Комментарий = НСтр(\"ru = 'Заполняет значение нового реквизита \"\"Статус заказа\"\" у документов \"\"Заказ покупателя\"\" прошлых периодов. Работа со старыми заказами временно невозможна.'\");

              \n

              4. Комментарий заполняется обязательно и не должен совпадать с комментариями к другим обработчиками обновления. Комментарий к обработчику должен давать администратору ответ на вопрос
              что именно и в каком объеме не будет работать в программе до завершения этого обработчика.
              Например:

              \n
                \n
              • Подготовка индекса для поиска отчетов, предусмотренных в программе. Поиск отчетов временно недоступен. \n
              • Реструктуризация дополнительных реквизитов и сведений. Рекомендуется воздержаться от их редактирования до завершения обработки. \n
              • Первоначальный расчет количества нерассмотренных писем по папкам. До завершения обработки всех писем, их количество может выводиться некорректно.  \n
              • Заполняются движения по новому регистру \"Движения Номенклатура-Контрагент\" по документам \"Расчет себестоимости товаров\". После выполнения обработки появится возможность формировать отчеты ...
              \n

              5. Синтаксис процедуры-обработчика отложенного обновления:

              \n

              Процедура ЗаполнитьСтатусыЗаказовПокупателей(Параметры) Экспорт

              \n

              где Параметры – Структура со свойствами:

              \n
                \n
              • ОбработкаЗавершена (Булево). Для того чтобы обработчик был вызван повторно для обработки следующей порции данных, следует записать в него значение Ложь. \n
              • ПрогрессВыполнения (Структура). (*) Необходимо заполнять для отображения прогресса обработки данных: \n
                  \n
                • ВсегоОбъектов (Число). Общее количество объектов, которые необходимо обработать. \n
                • ОбработаноОбъектов (Число). Сколько объектов уже обработано.
              \n

              (*) Примечание: актуально для версий БСП 2.3.1 и выше.

              \n

              6. Отложенную обработку данных необходимо выполнять порциями, чтобы не создавать длительную нагрузку на сервер предприятия и СУБД. По умолчанию, размер порции – 1000 (документов, записей и т.п.). Размер порции можно увеличить для небольших объектов и уменьшить для документов, в которых большие табличные части (в среднем).
              Также рекомендуется начинать обработку с самых \"свежих\" данных.
              Например:

              \n

               Запрос = Новый Запрос;
               Запросекст = 
               \"ВЫБРАТЬ ПЕРВЫЕ 1000
               | ЗаказПокупателясылка
               |ИЗ
               | Документ.ЗаказПокупателя КАК ЗаказПокупателя
               |ГДЕ
               | ЗаказПокупателя.СтатусЗаказа = &ПустаяСсылка
               |
               |УПОРЯДОЧИТЬ ПО
               | ЗаказПокупателя.Дата УБЫВ\";

              \n

              7. Поскольку отложенные обработчики обновления выполняются одновременно с работой пользователей в программе (а также с регламентными заданиями и другими сеансами), в их коде необходимо учитывать ошибки блокировки при обработке данных. Например, когда обрабатываемый документ редактируется пользователем или записывается другим сеансом. Такие ошибки следует фиксировать в журнале регистрации, а если не удалось обработать ни один из объектов порции - вызывать исключение.

              \n

               ПараметрыбработкаЗавершена = Ложь;
               
               ПроблемныхОбъектов = 0;
               ОбъектовОбработано = 0;
               
               Для Каждого ЗаказПокупателя Из РезультатЗапроса Цикл
                
                Попытка
                 
                 ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя); // обрабатываем очередной документ из порции
                 ОбъектовОбработано = ОбъектовОбработано + 1;
                 
                Исключение
                 // Если не удалось обработать какой-либо заказ, повторяем попытку снова.
                 ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
                 
                 ТекстСообщения = СтроковыеФункцииКлиентСерверодставитьПараметрыВСтроку(
                  НСтр(\"ru = 'Не удалось обработать заказ покупателя: %1 по причине:
                   |%2'\"), 
                   ЗаказПокупателя.Ссылка, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
                 ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
                  Метаданные.Документы._ДемоЗаказПокупателя, ЗаказПокупателясылка, ТекстСообщения);
                КонецПопытки;
                
               КонецЦикла;
               
               Если ОбъектовОбработано = 0 Тогда
                ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                 НСтр(\"ru = 'Процедуре ЗаполнитьСтатусыЗаказовПокупателей не удалось обработать некоторые заказы покупателей (пропущены): %1'\"), 
                  ПроблемныхОбъектов);
                ВызватьИсключение ТекстСообщения;
               Иначе
                ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
                 Метаданные.Документы._ДемоЗаказПокупателя,,
                  НСтр(\"ru = 'Процедура ЗаполнитьСтатусыЗаказовПокупателей обработала очередную порцию заказов покупателей: 50'\"));
               КонецЕсли;

              \n

              При этом после трех неудачных попыток выполнения (когда вызвано исключение), обработчик автоматически помечается как проблемный, а его выполнение останавливается. Как правило, это означает, что ошибка не связана с блокировкой данных, а вызывана некорректной работой самого обработчика или неконсистентными данными в базе. Проблемные обработчики ставятся в очередь на выполнение только при следующем обновлении, когда например, разработчик конфигурации исправляет выявленные ошибки в обработчике (или устраняет проблему с данными в базе) и выпускает исправительный релиз.

              \n

              8. Отложенные обработчики обновления должны самостоятельно заботиться о целостности обновляемых данных: при чтении данных с последующим изменением требуется выполнять эти действия в транзакции и устанавливать исключительную управляемую блокировку.

              \n

              Например:

              \n

              Процедура ЗаполнитьСтатусЗаказаПокупателя(ЗаказПокупателя)

               НачатьТранзакцию();
               Попытка
               
                Блокировка = Новый БлокировкаДанных;
                ЭлементБлокировки = Блокировкаобавить(\"Документ._ДемоЗаказПокупателя\");
                ЭлементБлокировкистановитьЗначение(\"Ссылка\", ЗаказПокупателя.Ссылка);
                Блокировка.Заблокировать();
                
                ДокументОбъект = ЗаказПокупателя.Ссылка.ПолучитьОбъект();

              \n

                // Если объект ранее был удален или обработан другими сеансами, пропускаем его.
                Если ДокументОбъект = Неопределено Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                Если ДокументОбъекттатусЗаказа <> Перечисления._ДемоСтатусыЗаказовПокупателейустаяСсылка() Тогда
                 ОтменитьТранзакцию();
                 Возврат;
                КонецЕсли;
                
                // Обрабатываем документ
                // ...
                
                ОбновлениеИнформационнойБазыаписатьДанные(ДокументОбъект);
                
                ЗафиксироватьТранзакцию();
               Исключение
                ОтменитьТранзакцию();
                ВызватьИсключение;
               КонецПопытки;

              \n

              КонецПроцедуры

              \n

              9. В общем случае, при обработке данных конкретной таблицы (документа, регистра и т.п.) – некоторая часть ее данных требуется пользователям сразу к моменту начала работы в новой версии программы, а все остальное может быть обработано отложенно. В таких случаях, рекомендуется реализовать два обработчика обновления: монопольный и отложенный.

              \n

              10. В редких случаях, когда в новой версии конфигурации появился монопольный (или оперативный) обработчик обновления, данные которого обрабатывались в предыдущих версиях отложенно, следует:

              \n
                \n
              • Пересмотреть проектное решение и сделать такой обработчик отложенным \n
              • Либо «старые» отложенные обработчики обновления нужно сделать монопольными (оперативными)
              \n

              В противном случае, возникнет ситуация, когда данные будут обработаны в неправильном порядке: сначала выполнятся монопольный (оперативный) обработчик, который рассчитывается на то, что данные были обработаны ранее отложенно.

              \n

              11. В целях оптимизации не рекомендуется разрабатывать несколько обработчиков, которые обрабатывают одни и те же данные. Реструктуризации одной таблицы следует выполнять однократно, чтобы минимизировать расходы на чтение и запись объектов (наборов записей).

              \n

              С этой целью каждый раз при выпуске новых версий конфигурации рекомендуется пересматривать все ранее разработанные отложенные обработчики, дополняя их реализацию новыми алгоритмами обновления (а не разрабатывать новые обработчики).

              \n

              Например, если ранее в конфигурации были предусмотрены обработчики обновления справочника Контрагенты для версий 1.5 и 2.0, то при разработке версии 2.5 в новый обработчик обновления этого справочника следует также поместить логику двух предыдущих, а их удалить. Тем самым, для пользователей значительно ускорится переход через несколько версий (с 1.0 на 2.5).

              \n

              Для этого в логику запроса, отбирающего данные, подлежащие обработке, следует включить все три условия по ИЛИ, а в алгоритме обновления (реструктуризации) дополнительно определять степень обработки этих данных.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "547", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована инструкция препроцессора в клиент-серверном общем модуле.", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n\n\n\n

              Использование директив компиляции и инструкций препроцессора

              #std439

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Директивы компиляции:

              \n

              &НаКлиенте (&AtClient)
              &НаСервере (&AtServer)
              &НаСервереБезКонтекста (&AtServerNoContext)

              \n

              следует применять только в коде модулей управляемых форм и в коде модулей команд. В остальных модулях рекомендуется применять инструкции препроцессору.

              \n

              В серверных или клиентских общих модулях контекст исполнения очевиден, поэтому смысла в директивах компиляции нет. В общих модулях с признаками клиент и сервер применение директив компиляции затрудняет понимание, какие же процедуры (функции) доступны в конечном итоге.

              \n

              2. Не следует использовать инструкции препроцессора в клиент-серверных общих модулях для проверки клиентского и серверного контекстов (#Если Сервер, #Если Клиент) ввиду невозможности надежного определения контекста исполнения. Процедуры и функции, которые работают по-разному при вызове с клиента и с сервера, следует размещать в общих модулях с постфиксами Клиент и Сервер, а не КлиентСервер.

              \n

              В противном случае невозможно гарантировать корректную работу клиент-серверных процедур и функций в различных режимах работы платформы 1С:Предприятие.

              \n

              Например, неправильно:

              \n

              Функция КодОсновногоЯзыка() Экспорт
              #Если НЕ ТонкийКлиент И НЕ ВебКлиент Тогда
               Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
              #Иначе
               Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(\"КодОсновногоЯзыка\");
              #КонецЕсли
              КонецФункции

              \n

              также неправильно:

              \n

              Функция КодОсновногоЯзыка() Экспорт
              #Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
               Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
              #Иначе
               Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(\"КодОсновногоЯзыка\");
              #КонецЕсли
              КонецФункции

              \n

              Правильно: разделить на две одноименные функции в серверном и клиентском модуле с различной реализацией. В общем случае, когда у них имеется определенная общая часть, одинаковая для клиента и сервера, то для того чтобы избежать дублирования кода, этот общий код (и только его) следует оставить в клиент-серверном общем модуле и вызывать его из клиентской и серверной функций, соответственно. Тем самым надежно достигается различное поведение в клиентском и серверном контекстах без использования инструкций препроцессора.

              \n

              В то же время, как и в обычных клиентских модулях, допустимо ветвление кода для учета специфики различных режимов работы клиентского приложения: веб-клиент, тонкий или толстый клиент (например, #Если ВебКлиент).

              \n

              3. Не следует разрывать инструкциями препроцессора и областями отдельные грамматические конструкции, выражения, а также объявления и места вызова процедур и функций.

              \n

              Например, неправильно:

              \n

              Процедура Пример1()
                а = 1
              #Область ИмяОбласти
                  + 2;
              #КонецОбласти // разрыв выражения
              КонецПроцедуры

              \n

              #Область ИмяОбласти
              Процедура Пример2()
                  // ...
              #КонецОбласти // разрыв процедуры
              КонецПроцедуры

              \n

              Если <...> Тогда
                  // ...
              #Если ВебКлиент Тогда // разрыв блока Если
              Иначе
                  // ...
              #КонецЕсли
              КонецЕсли;

              \n

              Результат = Пример4(Параметр1,
              #Если Клиент Тогда
                Параметр2, // некорректный вызов функции
              #КонецЕсли
                Параметр3);

              \n

              Данные ошибки диагностируются автоматически с помощью среды разработки 1C:Enterprise Development Tools (EDT).

              \n

              Правильно использовать инструкции препроцессора без разрыва конструкций.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "548", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Параметры вызова функции скопированы из определения вызываемой процедуры (функции).", +"Description": "

              Параметры процедур и функций

              #std640

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

              \n

              2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

              \n

              3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
              Например, неправильно:

              Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
              \n

              правильно сначала расположить основные параметры ДокументОбъект и Форма:

              Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
              \n

              4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
              Например:

              Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
              \n

              5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

              \n

              При необходимости передавать в функцию большое число параметров рекомендуется:

              \n
                \n
              • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
              • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
              \n

              Например, неправильно:

              // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
              \n

              Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

              // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
              \n

              Другой пример. Неправильно:

              // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
              \n

              Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

              // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
              \n

              6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
              В частности:

              \n

              6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
              Неправильно:

              СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
              \n

              Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

              АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
              \n

              В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
              Например:

              Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
              \n

              6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

              \n

              Неправильно:

              ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
              \n

              Правильно:

              ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
              \n

              7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

              \n

              Например, для вызова процедуры

              \n

              Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

              \n

              неправильно:

              ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
              \n

              правильно:

              ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "549", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Выполняется неявная передача обязательного параметра.", +"Description": "

              Параметры процедур и функций

              #std640

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. При объявлении формальных параметров процедур и функций (далее по тексту: функций) необходимо придерживаться общих правил образования имен переменных. В частности, имена параметров следует образовывать от терминов предметной области таким образом, чтобы из имени параметра было понятно его назначение.

              \n

              2. Не следует использовать вместо параметров функций другие средства конфигурирования (переменные модулей, реквизиты формы и т.п.)

              \n

              3. Параметры в функции должны идти в логической последовательности. Рекомендуется располагать параметры по принципу от общего к частному.
              Например, неправильно:

              Процедура ПересчитатьСуммуДокумента(ИмяПоляСумма, ДокументОбъект, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Цвет, ИмяПоля, Форма)\n
              \n

              правильно сначала расположить основные параметры ДокументОбъект и Форма:

              Процедура ПересчитатьСуммуДокумента(ДокументОбъект, ИмяПоляСумма, СуммаВключаетНДС = Истина)\n \nПроцедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)\n
              \n

              4. Необязательные параметры (параметры со значениями по умолчанию) должны располагаться после обязательных параметров (без значений по умолчанию).
              Например:

              Функция КурсВалютыНаДату(Валюта, Дата = Неопределено) Экспорт\n
              \n

              5. Не рекомендуется объявлять в функциях много параметров (нужно ориентироваться на количество не более семи параметров), при этом не должно быть много параметров со значениями по умолчанию (нужно ориентироваться на количество не более трех таких параметров). В противном случае, читаемость вызывающего кода сильно снижается. Например, можно легко ошибиться в количестве запятых при передаче необязательных параметров. 

              \n

              При необходимости передавать в функцию большое число параметров рекомендуется:

              \n
                \n
              • группировать однотипные параметры в один или несколько составных параметров типа Структура. Например, в структуры могут быть объединены параметры, описывающие состав и значения полей некоторого объекта (ДанныеЗаполнения, ПараметрыПроведения, ДанныеФайла и т.п.); \n
              • либо полностью пересмотреть логику работы функции, например, разделив ее на несколько разных, более простых функций.
              \n

              Например, неправильно:

              // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция ДобавитьПолеФормы(ИмяПоля,\n      Заголовок = Неопределено,\n      ОбработчикПриИзменении = \"\",\n      ОбработчикНачалоВыбора = \"\",\n      ШиринаПоля,\n      ЦветФона = Неопределено,\n      ЦветФонаЗаголовка = Неопределено,\n      Родитель = Неопределено,\n      КартинкаШапки = Неопределено,\n      ПутьКДанным = Неопределено,\n      ТолькоПросмотрПоля = Ложь,\n      СвязиПараметровВыбора = Неопределено)\n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = ДобавитьПолеФормы(\"СтараяЦена\", НСтр(\"ru='Цена'\"),,, 12, ЦветФона, ЦветЗаголовка, НоваяГруппа,,,Истина);\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\n
              \n

              Правильно пересмотреть логику работы функций, оставив в ней только один ключевой параметр ИмяПоля:

              // Добавляет новое поле на форму, инициализирует его значениями по умолчанию.\nФункция НовоеПолеФормы(ИмяПоля)  \n…\nКонецФункции\n\n// вызывающий код\nНовоеПоле = НовоеПолеФормы(\"СтараяЦена\");\nНовоеПоле.Заголовок  = НСтр(\"ru='Цена'\");\nНовоеПоле.ЦветФона   = ЦветФона;\nНовоеПоле.ЦветТекста = WebЦвета.Серый;\nНовоеПоле…. = …\n…\n
              \n

              Другой пример. Неправильно:

              // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(Наименование, ТоварУслуга, ЕдиницаИзмерения, ВесНетто, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
              \n

              Правильно сгруппировать параметры, описывающие значения реквизитов номенклатуры, в структуру ЗначенияРеквизитов:

              // Создает элемент справочника \"Номенклатура\"\nПроцедура СоздатьЭлементНоменклатуры(ЗначенияРеквизитов, ПроверятьУникальность = Истина)\n…\nКонецПроцедуры\n
              \n

              6. При вызове функций необходимо избегать громоздких конструкций, которые приводят к снижению читаемости кода, увеличивают вероятность ошибок и затрудняют отладку.
              В частности:

              \n

              6.1. Не рекомендуется при передаче параметров в одну функцию применять вложенные вызовы других функций.
              Неправильно:

              СтруктураВложений.Вставить(\n ПрисоединенныйФайл.Наименование,\n Новый Картинка(ПолучитьИзВременногоХранилища(\n  ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла)));\n
              \n

              Правильно разбивать такие вызовы на отдельные операторы с помощью вспомогательных локальных переменных:

              АдресФайлаИзображения = ПрисоединенныеФайлы.ПолучитьДанныеФайла(ПрисоединенныйФайл.Ссылка).СсылкаНаДвоичныеДанныеФайла;\nДанныеИзображения = Новый Картинка(ПолучитьИзВременногоХранилища(АдресФайлаИзображения));\nСтруктураВложений.Вставить(ПрисоединенныйФайл.Наименование, ДанныеИзображения);\n
              \n

              В то же время, если код с вложенными вызовами получается компактным (не требует переноса выражений) и легко читаемым, то вложенные вызовы допустимы.
              Например:

              Предупреждение(НСтр(\"ru='Для выполнения операции необходимо установить расширение работы с файлами.'\"));\n\nПеречитатьСуммуПоКурсу(Сумма, КурсВалютыНаДату(Валюта));\n
              \n

              6.2. Также не рекомендуется при вызове функций использовать вложенный конструктор структуры: Новый Структура(...). Вложенное объявление структуры допустимо только в тех случаях, когда количество ее свойств небольшое (нужно ориентироваться на количество свойств не более трех).

              \n

              Неправильно:

              ЗаполнитьЦены(\n  Объект.Товары, // Табличная часть\n  , // Массив строк или структура отбора\n  Новый Структура( // Параметры заполнения\n   \"Дата, Валюта, Соглашение, ПоляЗаполнения\",\n   Объект.Дата,\n   Объект.Валюта,\n   Объект.Соглашение,\n   \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\"\n  ),\n  Новый Структура( // Структура действий с измененными строками\n   \"ПересчитатьСумму, ПересчитатьСуммуСНДС, ПересчитатьСуммуНДС, ПересчитатьСуммуРучнойСкидки, ОчиститьАвтоматическуюСкидку, ОчиститьСуммуВзаиморасчетов\",\n   \"КоличествоУпаковок\", СтруктураПересчетаСуммы, СтруктураПересчетаСуммы, \"КоличествоУпаковок\", Неопределено, Неопределено\n  )\n );\n
              \n

              Правильно:

              ПараметрыЗаполнения = Новый Структура;\nПараметрыЗаполнения.Вставить(\"Дата\", Объект.Дата);\nПараметрыЗаполнения.Вставить(\"Валюта\", Объект.Валюта);\nПараметрыЗаполнения.Вставить(\"Соглашение\", Объект.Соглашение);\nПараметрыЗаполнения.Вставить(\"ПоляЗаполнения\", \"Цена, СтавкаНДС, ВидЦены, СрокПоставки\");\n \nДействияСИзмененнымиСтроками = Новый Структура;\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСумму\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуСНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуНДС\", ПараметрыПересчетыСуммы);\nДействияСИзмененнымиСтроками.Вставить(\"ПересчитатьСуммуРучнойСкидки\",\"КоличествоУпаковок\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьАвтоматическуюСкидку\");\nДействияСИзмененнымиСтроками.Вставить(\"ОчиститьСуммуВзаиморасчетов \");\n\nЗаполнитьЦены(Объект.Товары, ПараметрыЗаполнения, ДействияСИзмененнымиСтроками);\n
              \n

              7. При вызове функций не следует пропускать обязательные параметры. В противном случае, в параметр будет передано значение Неопределено, на которое функция может быть не рассчитана. Если же значение Неопределено является допустимым, то нужно или его передавать в функцию явно, или сделать этот параметр необязательным со значением по умолчанию Неопределено.

              \n

              Например, для вызова процедуры

              \n

              Процедура ПоменятьЦветПоляФормы(Форма, ИмяПоля, Цвет)

              \n

              неправильно:

              ПоменятьЦветПоляФормы(,\"РезультатПроверки\", ЦветаСтиля.ПоясняющийОшибкуТекст); // пропущен первый параметр Форма\nПоменятьЦветПоляФормы(,,); // пропущены все обязательные параметры\n
              \n

              правильно:

              ПоменятьЦветПоляФормы(ЭтотОбъект, \"РезультатПроверки\", Цвет); // указаны все обязательные параметры
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "552", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Небезопасное подключение внешней обработки.", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "553", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Небезопасное подключение внешнего отчета.", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "554", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Небезопасное подключение расширения конфигурации.", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "555", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Создание объекта типа \"ОписаниеЗащитыОтОпасныхДействий\".", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "556", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Вызов функции БСП \"ОбщегоНазначения.ОписаниеЗащитыБезПредупреждений()\".", +"Description": "

              Ограничение на выполнение «внешнего» кода

              #std669

              Область применения: управляемое приложение, обычное приложение.

              \n

              Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. Пример такой уязвимости: https://1c.ru/news/info.jsp?id=21537

              \n

              Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса.

              \n

              1. Для прикладных решений запрещено выполнение в небезопасном режиме любого кода на сервере 1С:Предприятия, который не является частью самого прикладного решения (конфигурации). Ограничение не распространяется на код, прошедший аудит, и на код, выполняемый на клиенте.

              \n

              Примеры недопустимого выполнения «внешнего» кода в небезопасном режиме:

              \n
                \n
              • внешние отчеты и обработки (печатные формы и т.п.), расширения конфигурации, внешние компоненты и любые другие аналогичные возможности, с помощью которых пользователи подключают к конфигурации внешний код; \n
              • алгоритмы на встроенном языке, тексты запросов или их фрагменты, которые пользователи интерактивно вводят в режиме 1С:Предприятия, и которые затем передаются в методы глобального контекста Выполнить или Вычислить (см. «Ограничения на использование Выполнить и Вычислить на сервере»); \n
              • изменение пользователями схем компоновки данных в отчетах, в которых разрешено использование внешних функций (эта возможность закрыта при использовании стандартной формы отчета: она не позволяет пользователям изменять схему компоновки  данных, а из пользовательских полей использовать  функции общих модулей нельзя). В том числе, возможность загрузки пользователями схем компоновки данных из внешних файлов.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) внешний код допустимо подключать только через соответствующие подсистемы БСП:

              \n
                \n
              • как расширения конфигурации – с помощью средств подсистемы «Базовая функциональность»; \n
              • как внешние отчеты и обработки – через «Дополнительные отчеты и обработки»; \n
              • в виде внешних компонент – через подсистему «Внешние компоненты»; \n
              • для запуска внешних программ – см. Безопасность запуска приложений.
              \n

              При этом указанное в этом пункте требование будет выполнено.

              \n

              2. По умолчанию, в конфигурации для всех категорий пользователей должна быть отключена возможность интерактивно открывать внешние отчеты и обработки через меню Файл – Открыть. См. пп. 2.2 и 2.3 Стандартные роли.
              При этом в настройках программы должна быть предусмотрена обратная возможность разрешить это действие. В случае если администратор разрешает интерактивно открывать внешние отчеты и обработки, то информировать его и пользователей о том, что при открытии файлов внешних отчетов и обработок следует обращать особое внимание на их источник и не открывать файлы, полученные из источников, с которыми нет договоренности о разработке таких отчетов и обработок.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем отключение интерактивного открытия внешних отчетов и обработок, настройка, а также соответствующие предупреждения уже предусмотрены.

              \n

              3. Предупреждать администраторов об опасности перед подключением любого внешнего кода.

              \n

              3.1. Выводимая информация должна включать в себя в явном виде сведения, что внешний код, полученный из недостоверных источников (с которыми, например, нет договоренности о разработке такого кода), может нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. При этом администратор должен иметь возможность отказаться от загрузки внешнего кода (а также возможно повторить его загрузку позднее после проведения соответствующего аудита). 

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем такие предупреждения для администратора уже предусмотрены в соответствующих подсистемах.

              \n

              3.2. В то же время, остальные пользователи программы не должны получать дополнительных предупреждений при исполнении внешнего кода, подключение которого ранее было явно подтверждено администратором.
              Для программного отключения см. раздел 7.10.2. Отключение механизма защиты от опасных действий в документации к платформе 1С:Предприятие.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем

              \n
                \n
              • подобное отключение предупреждений уже предусмотрено в соответствующих подсистемах; \n
              • запрещено отключать предупреждения об опасных действиях во всех остальных случаях.
              \n

              4. Если в конфигурации предусмотрены средства обновления конфигурации (из файлов .cf, .cfu), восстановления из резервной копии или загрузки из dt-файла в режиме 1С:Предприятия, то эти операции должны выполняться с соблюдением следующих правил:

              \n

              \n
                \n
              • обновление должно быть доступно только пользователю с ролью «Администратор системы»; \n
              • такое обновление должно выполняться только интерактивно текущим пользователем, а не служебным пользователем с полными правами; \n
              • перед обновлением конфигурации из файла или восстановления из резервной копии, администратору должно показываться предупреждение о том, что он должен убедиться, что файл обновления получен из надежного источника; \n
              • при обновлении конфигурации через Интернет, должно использоваться защищенное соединение (см. п. 7) и надежный источник, о чем нужно предупредить пользователя, когда он настраивает параметры подключения к источнику обновления.
              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) операции обновления конфигурации и восстановления из резервной копии следует выполнять только средствами подсистем «Обновление конфигурации» и «Резервное копирование ИБ» БСП. При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              5. Если в конфигурации предусмотрены средства загрузки произвольных файлов в программу, то следует также иметь в виду, что они могут содержать вредоносный исполняемый код.
              В этом случае в конфигурации следует предусмотреть

              \n
                \n
              • для администратора – дополнительные средства контроля, в частности, список разрешенных (запрещенных) расширений файлов для загрузки в программу; \n
              • блокирование открытия исполняемых файлов из программы (даже если их разрешено загружать и хранить в программе).
              \n

              Примечание: в общем случае, вредоносный код может содержаться даже в неисполняемых файлах, например, макровирусы в документах Microsoft Office. Однако в этом случае необходимые предупреждение об опасных действиях уже предусмотрены в сторонних приложениях Microsoft Office, поэтому в конфигурации не требуется предпринимать дополнительных мер защиты. Исключение составляет случай открытия через COM – см. Безопасность программного обеспечения, вызываемого через открытые интерфейсы.

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем (БСП) работу с файлами следует организовывать только средствами подсистемы «Работа с файлами». При этом автоматически будут выполнены все требования, перечисленные выше в этом пункте.

              \n

              6. Безопасность внешних компонент.

              \n

              6.1. Внешние компоненты, не являющиеся частью конфигурации (не размещенные в макетах конфигурации) потенциально опасны и их не следует загружать из источников, к которым нет доверия, с целью последующей установки и подключения. Пользователи без административных прав не должны иметь возможности загрузки, установки и подключения внешних компонент на сервере прикладного решения. При этом пользователю всегда должен задаваться вопрос и предоставляться выбор, устанавливать ли внешний компонент на клиенте.

              \n

              Невыполнение этих требований может нарушить работоспособность и безопасность прикладного решения, серверов на которых оно работает и компьютера пользователя.

              \n

              6.2. Сторонние внешние компоненты следует хранить в специальном справочнике, доступ на запись к которому есть только у администратора и подключать их только по навигационной ссылке на реквизит справочника, в котором хранятся двоичные данные компоненты.

              \n

              Не следует подключать сторонние внешние компоненты по имени файла или по идентификатору программы, т.к. в этом случае злоумышленник сможет подменить путь к файлу или идентификатор программы и подключить свою вредоносную компоненту.

              \n

              6.3. Внешние компоненты, входящие в состав конфигурации, должны храниться в макетах типа «Внешняя компонента». Данный тип макета не локализуется.

              \n

              6.4. При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать методы подключения компонент библиотеки и полностью исключить непосредственное использование платформенных механизмов подключения внешних компонент, таких как:

              \n
                \n
              • ПодключитьВнешнююКомпоненту; \n
              • НачатьУстановкуВнешнейКомпоненты; \n
              • УстановитьВнешнююКомпоненту; \n
              • НачатьПодключениеВнешнейКомпоненты; \n
              • ЗагрузитьВнешнююКомпоненту.
              \n

              Для подключения компоненты из макета в составе конфигурации на клиенте следует использовать:

              \n

              ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компоненты из макета в составе конфигурации на сервере следует использовать:

              \n

              ОбщегоНазначения.ПодключитьКомпонентуИзМакета

              \n

              Для подключения компонент из хранилища внешних компонент (специального справочника  с возможностью обновлять компоненты независимо от обновления конфигурации), следует использовать подсистему Внешние компоненты в Библиотеке стандартных подсистем:

              \n

              ВнешниеКомпонентыКлиент.ПодключитьКомпоненту

              \n

              7. При загрузке внешнего кода из удаленных источников в конфигурацию, следует:

              \n
                \n
              • использовать только надежные источники, к которым есть доверие; \n
              • выполнять передачу данных только по защищенным каналам связи.
              \n

              ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем необходимо использовать функцию НовоеЗащищенноеСоединение общего модуля ОбщегоНазначенияКлиентСервер:

              \n

              ЗащищенноеСоединение = ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение();
              Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "557", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Экспортная процедура (функция) из модуля с признаком \"ВызовСервера\" не вызывается на клиенте.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "558", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Экспортная процедура (функция) из модуля с признаком \"КлиентСервер\" не вызывается на клиенте.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "559", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Экспортная процедура (функция) из модуля с признаком \"КлиентСервер\" не вызывается на сервере.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 20 +}, +{ +"Code": "561", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "562", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Возможно ошибочное свойство.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "563", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Возможно ошибочный метод.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "564", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Возможно ошибочный параметр.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "565", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Ошибка платформенной проверки конфигурации: Использование модального вызова.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 20 +}, +{ +"Code": "566", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Использование синхронного вызова.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "567", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Не обнаружено ссылок на процедуру.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "568", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Не обнаружено ссылок на функцию.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "569", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Неразрешимые ссылки на объекты метаданных.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "570", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Отсутствует обработчик.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "571", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Переменная не определена.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "572", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Процедура или функция с указанным именем не определена.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n\n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "573", +"Type": "BUG", +"Severity": "BLOCKER", +"Name": "Ошибка платформенной проверки конфигурации: Пустой обработчик.", +"Description": "

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              \n\n\n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "574", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Ошибка платформенной проверки конфигурации: (Проверка: Мобильный клиент).", +"Description": "\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              \n\n\n

              Несущественные предупреждения проверки конфигурации

              #std759

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Следующие предупреждения проверки конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…) не являются существенными для работоспособности прикладных решений и поэтому не подлежат обязательному исправлению:

              \n
                \n
              • Пустой обработчик (для обработчиков оповещений в программных модулях); \n
              • Неразрешимые ссылки на объекты метаданных (в формах и в справке); \n
              • Неразрешимые ссылки на картинки (в формах); \n
              • Неправильные пути к данным (в формах).
              \n

              Кроме того методика поиска и исправления подобных мест отсутствует.

              \n

              2. При регламентной проверке конфигурации не следует включать флажок Поиск использования синхронных вызовов, так как в результатах проверки выводятся, в том числе, корректные места вызовов в коде, который не исполняется в веб-клиенте (например, серверный код). См. также: Ограничение на использование модальных окон и синхронных вызовов.

              \n

              См. также

              \n\n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "58", +"Type": "BUG", +"Severity": "INFO", +"Name": "Имя неверно образовано из синонима.", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n", +"Active": false, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "580", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Нет вызовов служебной экспортной процедуры (функции).", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 30 +}, +{ +"Code": "581", +"Type": "BUG", +"Severity": "MAJOR", +"Name": "Избыточное ключевое слово \"Экспорт\".", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 10 +}, +{ +"Code": "59", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Подсказка совпадает с синонимом.", +"Description": "

              Подсказка и проверка заполнения

              #std478

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.1. Свойство «Подсказка». Задается для тех объектов (реквизитов объектов, реквизитов табличных частей, измерений и ресурсов регистров), которые выводятся пользователю в виде элементов интерфейса и которые требуют пояснения, расшифровки и донесения до пользователя подробного описания их назначения. Для реквизитов, используемых в ежедневной работе, подсказки добавлять не следует.

              \n

              В тексте подсказки не рекомендуется приводить инструкции и объяснять работу реквизита, вместо этого следует оптимизировать сценарии работы, с ним связанные.

              \n

              При этом бессмысленные подсказки, автоматические генерируемые конфигуратором при создании элементов управления (групп) на формах, нужно не забывать очищать. Например, «Группа шапка» и пр.

              \n
              \n

              См. также: Подсказки на форме, Подсказки для интерфейсных подсистем, Тексты

              \n

              2.1. Свойство «Проверка заполнения». Для всех типизированных объектов метаданных, а также для стандартных реквизитов и табличных частей, которые в соответствии с логикой объекта являются обязательными к заполнению, свойство \"Проверка заполнения\" должно быть установлено в \"Выдавать ошибку\".

              В ряде случаев проведение документа с незаполненными реквизитами и табличными частями не имеет смысла с точки зрения отражения документа в учете. Например, документ Заказ клиента является запросом клиента на поставку определенного количества товара. Из определения понятно, что методически заказ с незаполненным клиентом и незаполненной табличной частью Товары не имеет смысла, поэтому у реквизита Клиент и табличной части Товары свойство \"Проверка заполнения\" должно быть установлено в \"Выдавать ошибку\".

              \n

              2.2. При установке свойства «Проверка заполнения» следует исходить из того, что все ограничения и проверки должны быть (насколько это возможно полно) описаны в метаданных конфигурации. Поэтому если хотя бы один из сценариев работы с объектом требует обязательного заполнения реквизита, то свойство «Проверка заполнения» устанавливается в «Выдавать ошибку». Если в других сценариях работы заполнять реквизит не обязательно, то такие случаи должны быть предусмотрены в обработчике события модуля объекта ОбработкаПроверкиЗаполнения.

              \n

              При этом не следует придерживаться обратной схемы, когда свойство «Проверка заполнения» установлено в «Не проверять», а в обработчике ОбработкаПроверкиЗаполнения дописаны какие-либо проверки заполнения. Такая схема затрудняет анализ логики работы конфигурации.

              \n

              2.3. Если проверка заполнения реквизита зависит от тех или иных условий, рекомендуется управлять автопометкой незаполненного значения с помощью условного оформления форм объектов. Убирать ее в случае, если при данном состоянии объекта заполнение реквизита проверять не требуется.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "6", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Комментарий содержит букву \"ё\".", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "60", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не заполнен синоним конфигурации.", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "61", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "В имени конфигурации запрещено использовать слова \"редакция\" или \"подредакция\".", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "62", +"Type": "BUG", +"Severity": "INFO", +"Name": "Неверно указан адрес информации о поставщике. Должен быть \"http://www.1c.ru\".", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": false, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "63", +"Type": "BUG", +"Severity": "INFO", +"Name": "Неверно указан адрес информации о конфигурации. Должен начинаться с \"http://v8.1c.ru/\".", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": false, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "64", +"Type": "BUG", +"Severity": "INFO", +"Name": "Неверно указан адрес каталога обновлений. Должен быть \"http://downloads.v8.1c.ru/tmplts/\".", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": false, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "65", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использован метод \"ПолучитьФорму()\".", +"Description": "

              Открытие форм

              #std404

              Область применения: управляемое приложение, мобильное приложение.

              \n

              1. Для открытия форм следует применять метод глобального контекста ОткрытьФорму (при использовании версии платформы 1С:Предприятие 8.2 и более ранних версий - также ОткрытьФормуМодально). Применение альтернативного способа, с получением формы и ее последующим открытием с помощью метода ПолучитьФорму, не рекомендуется.

              Рекомендация обусловлена соображениями 

              \n
                \n
              • повышения устойчивости кода, работающего с формой, за счет разделения программного интерфейса для работы с формой и деталей ее внутренней реализации, \n
              • а также сохранения единой стилистики кода прикладных решений.
              \n

              Кроме того, применение глобального метода ОткрытьФорму гарантирует выполнение инициализации формы на сервере в обработчике ПриСозданииНаСервере. Этот подход помогает сосредоточить весь код инициализации формы в одном месте и исключает \"случайное\" обращение к серверу, связанное с инициализацией формы, между строками кода

              \n

              Форма = ПолучитьФорму(...)

              \n

              и

              \n

              Форма.ОткрытьФорму(...)

              \n
              \n

              См. также: раздел «Открытие управляемой формы» статьи «Минимизация количества серверных вызовов»

              \n

              2. В случаях когда форма требует параметризации при открытии, все ее параметры следует указывать в наборе параметров формы. Таким образом, набор параметров формы декларативно описывает возможности формы по ее параметризации.

              \n

              Параметры формы из этого набора могут быть указаны в вызывающем коде при открытии формы (ОткрытьФорму).

              \n

              3. Не следует применять другие способы параметризации формы при открытии. Например, нужно избегать обращения к методам и свойствам формы после ее открытия.
              Например, вместо

              \n

              МояФорма = Форма.ОткрытьФорму(\"ОбщаяФорма.ПутеводительПоСистеме\");
              МояФорма.Элементы.ГруппаШаг.ТекущаяСтраница = МойФорма.Элементы.ГруппаШаг.Страницы.Приветствие;

              \n

              следует по той же причине использовать параметры формы:

              \n

              ОткрытьФорму(\"ОбщаяФорма.ПутеводительПоСистеме\", Новый Структура(\"РежимОткрытия\", \"Приветствие\"));

              \n

              4. Для получения результата работы формы, вместо непосредственного обращения к элементам и реквизитам формы

              \n

              ФормаВопроса = ПолучитьФорму(\"ОбщаяФорма.ФормаВопроса\");
              ФормаВопроса.ОткрытьМодально();
              Если ФормаВопроса.БольшеНеПоказыватьНапоминание Тогда
              // …

              \n

              следует использовать процедуры-обработчики оповещений, которые будут вызваны при завершении работы пользователя с формой:

              \n

              Оповещение = Новый ОписаниеОповещения(\"БольшеНеПоказыватьНапоминаниеЗавершение\", ЭтотОбъект);
              ОткрытьФорму(\"ОбщаяФорма.ФормаВопроса\",,,,, Оповещение, РежимОткрытияОкнаФормы.БлокироватьВеcьИнтерфейс);
              ...

              \n

              &НаКлиенте
              Процедура БольшеНеПоказыватьНапоминаниеЗавершение(БольшеНеПоказыватьНапоминание, Параметры) Экспорт

                Если БольшеНеПоказыватьНапоминание = Неопределено Тогда
                  Возврат;
                КонецЕсли;  

              \n

                Если БольшеНеПоказыватьНапоминание Тогда
                // …

              \n

              КонецПроцедуры

              \n

              При этом возвращаемое значение формы формируется в коде модуля формы с помощью метода формы Закрыть.

              \n
              \n

              См. также: Ограничения на использование экспортных процедур и функций

              \n

              5. Другие ограничения:

              \n
                \n
              • Обработчик события формы ПриОткрытии не должен содержать код по открытию какой-либо другой формы, так как это может привести к нарушению порядка отображения окон. В этом случае рекомендуется использовать обработчик ожидания на короткий интервал или открывать другие формы интерактивно, например, по нажатию на кнопку. \n
              • Не рекомендуется выполнять программное открытие и закрытие формы в одном обработчике. Такие действия должны быть разнесены по времени. Например, закрытие формы можно выполнять в обработчике ожидания. \n
              • При использовании в конфигурации Библиотека стандартных подсистем  и разработке форм (рабочих мест), предназначенных только для внешних пользователей, следует явно блокировать открытие таких форм в сеансах \"обычных\" пользователей. Для этого следует устанавливать параметр Отказ при создании формы на сервере с помощью функции ЭтоСеансВнешнегоПользователя общего модуля Пользователи или ПользователиКлиент:
              \n

              &НаСервере
              Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
               
                Если Не ПользователиКлиентСервер.ЭтоСеансВнешнегоПользователя() Тогда
                  Отказ = Истина;
                  Возврат;
                КонецЕсли;
                …
              КонецПроцедуры

              \n

              6. Следующие виды форм должны быть всегда доступны пользователю в режиме 1С:Предприятия из меню \"Все функции\" вне зависимости от того, размещены ли соответствующие объекты в командном интерфейсе приложения или нет:

              \n
                \n
              • \n
                основная форма списка (для всех объектов)
                \n
              • \n
                основная форма обработки
                \n
              • \n
                основная форма отчета
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "66", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована конструкция \"ДЛЯ ИЗМЕНЕНИЯ\".", +"Description": "

              Использование управляемого режима блокировки

              #std460

              Область применения: управляемое приложение, обычное приложение.

              \n

              В конфигурациях следует использовать \"Управляемый\" режим блокировок (свойство Режим управления блокировкой данных конфигурации устанавливается в значение Управляемый) и учитывать особенности работы в этом режиме, в частности:

              \n
                \n
              • Чтение данных другими транзакциями будет невозможно только в том случае, если в текущей и других транзакциях устанавливаются несовместимые управляемые блокировки. \n
              • Явная управляемая блокировка должна устанавливаться перед чтением данных:  \n
                  \n
                • если считываются данные, которые в дальнейшем должны быть изменены;  \n
                • необходимо обеспечить неизменность считываемых данных до конца транзакции.
                \n
              • При установке управляемой блокировки необходимо стремиться, чтобы блокировка была установлена только на те записи, которые будут обработаны системой в результате отработки программного кода. \n
              • Не следует применять в запросах конструкцию ДЛЯ ИЗМЕНЕНИЯ, как не имеющую смысла в этом режиме.
              \n

              При работе в автоматическом режиме управления блокировкой 1С:Предприятие устанавливает высокую степень изоляции данных в транзакции на уровне СУБД. Это позволяет полностью исключить возможность получения нецелостных или некорректных данных без каких-либо специальных усилий со стороны прикладных разработчиков.

              \n

              Но, при этом могут возникать избыточные блокировки на уровне СУБД. Эти блокировки связанны как с особенностями реализации механизмов блокировок в самой СУБД, так и с тем, что СУБД не может учитывать (и не учитывает) физический смысл и структуру объектов метаданных 1С:Предприятия.

              \n

              См. такке

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 30 +}, +{ +"Code": "67", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Для конфигурации не установлен управляемый режим блокировки данных.", +"Description": "

              Использование управляемого режима блокировки

              #std460

              Область применения: управляемое приложение, обычное приложение.

              \n

              В конфигурациях следует использовать \"Управляемый\" режим блокировок (свойство Режим управления блокировкой данных конфигурации устанавливается в значение Управляемый) и учитывать особенности работы в этом режиме, в частности:

              \n
                \n
              • Чтение данных другими транзакциями будет невозможно только в том случае, если в текущей и других транзакциях устанавливаются несовместимые управляемые блокировки. \n
              • Явная управляемая блокировка должна устанавливаться перед чтением данных:  \n
                  \n
                • если считываются данные, которые в дальнейшем должны быть изменены;  \n
                • необходимо обеспечить неизменность считываемых данных до конца транзакции.
                \n
              • При установке управляемой блокировки необходимо стремиться, чтобы блокировка была установлена только на те записи, которые будут обработаны системой в результате отработки программного кода. \n
              • Не следует применять в запросах конструкцию ДЛЯ ИЗМЕНЕНИЯ, как не имеющую смысла в этом режиме.
              \n

              При работе в автоматическом режиме управления блокировкой 1С:Предприятие устанавливает высокую степень изоляции данных в транзакции на уровне СУБД. Это позволяет полностью исключить возможность получения нецелостных или некорректных данных без каких-либо специальных усилий со стороны прикладных разработчиков.

              \n

              Но, при этом могут возникать избыточные блокировки на уровне СУБД. Эти блокировки связанны как с особенностями реализации механизмов блокировок в самой СУБД, так и с тем, что СУБД не может учитывать (и не учитывает) физический смысл и структуру объектов метаданных 1С:Предприятия.

              \n

              См. такке

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "68", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использована конструкция \"ДанныеФормыВЗначение()\".", +"Description": "

              Использование РеквизитФормыВЗначение и ДанныеФормыВЗначение

              #std409

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              В большинстве случаев, в модулях форм следует использовать метод формы РеквизитФормыВЗначение вместо метода ДанныеФормыВЗначение

              \n

              Рекомендация обусловлена соображениями унификации прикладного кода и тем, что синтаксис метода РеквизитФормыВЗначение проще, чем у ДанныеФормыВЗначение (а следовательно, меньше вероятность ошибки).
              В ДанныеФормыВЗначение необходимо дополнительно передавать тип значения:

              \n

              ТаблицаПодписей = ДанныеФормыВЗначение(ТаблицаПодписей, Тип(\"ТаблицаЗначений\"));

              \n

              а для РеквизитФормыВЗначение это не обязательно, а в практическом плане - избыточно:

              \n

              ТаблицаПодписей = РеквизитФормыВЗначение(\"ТаблицаПодписей\");

              \n

              Наличие в платформе 1С:Предприятие метода формы РеквизитФормыВЗначение (наряду с методом глобального контекста ДанныеФормыВЗначение) объясняется только удобством его применения. С точки зрения эффективности и результата методы работают одинаково.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "69", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использован метод \"Сообщить()\".", +"Description": "

              Ограничение на использование метода Сообщить

              #std418

              Область применения: управляемое приложение.

              \n

              Для вывода сообщений пользователю во всех случаях следует использовать объект СообщениеПользователю, даже когда сообщение не «привязывается» к некоторому элементу управления формы. Метод Сообщить применять не следует.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              При использовании в конфигурации Библиотеки стандартных подсистем рекомендуется использовать процедуру СообщитьПользователю общего модуля ОбщегоНазначения или ОбщегоНазначенияКлиент, которая работает с объектом СообщениеПользователю.

              \n

              См. также

              \n
              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "7", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Синоним содержит букву \"ё\".", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "70", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использована конструкция \"ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ\".", +"Description": "

              Ограничение на использование конструкции \"ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ\" в запросах

              #std435

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              1.1. При разработке текстов запросов следует иметь в виду, что при работе в клиент-серверном варианте, когда в качестве СУБД используется PostgreSQL, производительность выполнения запросов с конструкцией ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ значительно снижается. В особенности это касается случаев, когда в запросе встречаются две и более таких конструкций.

              \n

              Поэтому в общем случае не рекомендуется использовать конструкцию ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ в запросах. И в тех случаях, где это возможно, рекомендуется переписать текст исходного запроса без использования этой конструкции.

              \n

              Например, следующий запрос:

              \n

              ВЫБРАТЬ
               ЕСТЬNULL(ПланПродаж.Номенклатура, ФактическиеПродажи.Номенклатура) КАК Номенклатура,
               ЕСТЬNULL(ПланПродаж.Сумма, 0) КАК СуммаПлан,
               ЕСТЬNULL(ФактическиеПродажи.Сумма, 0) КАК СуммаФакт
              ИЗ
               ПланПродаж КАК ПланПродаж
                ПОЛНОЕ СОЕДИНЕНИЕ ФактическиеПродажи КАК ФактическиеПродажи
                ПО ПланПродаж.Номенклатура = ФактическиеПродажи.Номенклатура

              \n

              может быть реализован без конструкции  ПОЛНОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ следующим образом:

              \n

              ВЫБРАТЬ
               ПланФактПродаж.Номенклатура КАК Номенклатура,
               СУММА(ПланФактПродаж.СуммаПлан) КАК СуммаПлан,
               СУММА(ПланФактПродаж.СуммаФакт) КАК СуммаФакт
              ИЗ
               (ВЫБРАТЬ
                ПланПродаж.Номенклатура КАК Номенклатура,
                ПланПродаж.Сумма КАК СуммаПлан,
                0 КАК СуммаФакт
               ИЗ
                ПланПродаж КАК ПланПродаж
               
               ОБЪЕДИНИТЬ ВСЕ
               
               ВЫБРАТЬ
                ФактическиеПродажи.Номенклатура,
                0,
                ФактическиеПродажи.Сумма
               ИЗ
                ФактическиеПродажи КАК ФактическиеПродажи) КАК ПланФактПродаж

              \n

              СГРУППИРОВАТЬ ПО
               ПланФактПродаж.Номенклатура

              \n

              1.2. Исключение составляют случаи, когда текст исходного запроса не может быть переписан без использования конструкции ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ по объективным причинам. Следует иметь в виду, что при выполнении данной конструкции на СУБД PostgreSQL она автоматически заменяется платформой 1С:Предприятие на эквивалентную, которая может быть исполнена в СУБД PostgreSQL. При этом сохраняются все атрибуты запроса, такие как модификаторы ПЕРВЫЕ, РАЗЛИЧНЫЕ, а также УПОРЯДОЧИТЬ ПО. В таких случаях не следует \"механически\" заменять конструкцию ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ только с той целью, чтобы от нее избавиться в тексте запроса.

              \n

              2. Не допускается одновременно использовать конструкцию ПОЛНОЕ СОЕДИНЕНИЕ и обращение к табличным частям из раздела ВЫБРАТЬ.

              \n

              Данное требование продиктовано особенностью выполнения подобных запросов на СУБД PostgreSQL и необходимостью переносимости прикладных решений на эту СУБД.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "71", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Неверно установлен номер версии. Он не должен быть вида 0.0.0.0, N.0.0.0, N.0.N.0 или N.0.0.N.", +"Description": "

              Нумерация редакций и версий

              #std483

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Номер очередной редакции конфигурации, начинается со следующего целого номера относительно предыдущей редакции. Для обозначения редакции обычно номер редакции объединяют через точку с номером подредакции, например: редакция 1.5, редакция 1.6 и т. д. Для новых конфигураций нумерация начинается с 1.0.

              2. Все версии одной подредакции (включая альфа, ознакомительные, бета и финальные версии) нумеруются подряд. Нумерация версий начинается с 1.

              3. Информация о номере редакции, номере подредакции и номере версии объединяются в полный номер версии конфигурации. Он указывается в свойстве Версия конфигурации и представляет собой строку символов следующего вида:

              {Р|РР}.{П|ПП}.{З|ЗЗ}.{С|СС}

              где:
              Р - номер редакции (минимум 1 цифра, может занимать и больше разрядов);
              П - номер подредакции (минимум 1 цифра, может занимать и больше разрядов);
              З - номер версии (минимум 1 цифра, может занимать и больше разрядов);
              С - номер сборки (минимум 1 цифра, может занимать и больше разрядов).

              Пример:

              \n
              \n
              1.6.4.7 – 7-я сборка, 4-ой версии, редакции 1.6
              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "72", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Синоним должен оканчиваться на номер редакции.подредакции.", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "73", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Рекомендуется избегать в названии общего модуля таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п.", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "75", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Отсутствует обязательная конструкция \"Если ОбменДанными.Загрузка Тогда ...\".", +"Description": "

              Обработчик события ПередУдалением

              #std752

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В данном обработчике модуля объекта, как правило, должны выполняться действия, которые необходимо выполнить перед удалением объекта. Например, перед удалением присоединенного файла может потребоваться произвести очистку ссылок на этот файл в объекте-владельце.

              \n

              2. Все действия в процедуре-обработчике события ПередУдалением должны выполняться после проверки на ОбменДанными.Загрузка.

              \n

              Т. е. они не должны выполняться перед удалением объекта через механизм обмена данными, так как это может привести к ошибкам. Примером таких ошибок является обращение к предопределенным объектам после очистки области данных.

              \n\n\n

              Обработчик события ПередЗаписью

              #std464

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В данном обработчике модуля объекта, как правило, должны выполняться действия, связанные с заполнением значений реквизитов объекта (набора записей, значения константы; далее упрощенно - \"объект\"), проверки правильности их заполнения, связанности состояния объекта с некоторыми внешними данными. Также в данном обработчике следует выполнять действия, связанные с обращением к \"старым\" значениям реквизитов объекта, сохраненным в базу данных (имеет смысл при редактировании уже записанных ранее объектов, наборов записей и т.п.).

              \n
              \n

              См. также раздел «Проверки, выполняемые в и вне транзакции записи объекта» статьи «Обработчик события ОбработкаПроверкиЗаполнения»

              \n

              2. Все действия в процедуре-обработчике события ПередЗаписью должны выполняться после проверки на ОбменДанными.Загрузка.

              \n\n\n

              Обработчик события ПриЗаписи

              #std465

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. В данном обработчике модуля объекта (набора записей, значения константы; далее - \"объект\"), как правило, выполняются действия по записи связанной с объектом данных в других объектах конфигурации, а также выполняются другие действия, связанные с изменением объекта.

              Запрещается в данном обработчике изменять содержимое записываемого объекта, поскольку на момент выполнения обработчика, объект уже записан в БД.

              \n

              2. Все действия в процедуре-обработчике события ПриЗаписи должны выполняться после проверки на ОбменДанными.Загрузка.

              \n

              См. также

              \n\n\n\n

              Использование признака ОбменДанными.Загрузка в обработчиках событий объекта

              #std773

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Все действия в процедурах-обработчиков событий ПередЗаписью, ПриЗаписи, ПередУдалением должны выполняться после проверки на ОбменДанными.Загрузка:

              \n

              Процедура ПередЗаписью(Отказ)
              Если ОбменДанными.Загрузка Тогда
                   Возврат;
              КонецЕсли;

              \n

              // код обработчика
              // ...
              КонецПроцедуры

              \n

              Это необходимо для того, чтобы никакая бизнес-логика объекта не выполнялась при записи объекта через механизм обмена данными, поскольку она уже была выполнена для объекта в том узле, где он был создан. В этом случае все данные загружаются в ИБ «как есть», без искажений (изменений), проверок или каких-либо других дополнительных действий, препятствующих загрузке данных.

              \n

              Кроме механизма обмена данными есть и другие случаи, когда это должно быть так. В общем виде следует руководствоваться следующим подходом: механизмы, не рассчитанные на особенности конкретных конфигураций, должны иметь возможность загрузить данные при установленном флаге загрузки так, как будто текста обработчика нет вообще:

              \n

              Объект.ОбменДанными.Загрузка = Истина;
              Объект.Записать();

              \n

              Например, требуется загрузить всю базу из XML «как есть». Для этого должно быть достаточно установить записываемым объектам ОбменДанными.Загрузка = Истина и все данные должны загрузиться без искажений, проверок и дополнительных  действий, т. е. так же как и при пустом обработчике.

              \n

              2. Исключение составляет механизм обмена данными, который в ходе загрузке данных в базу регистрирует эти данные к выгрузке на других узлах плана обмена.

              \n

              В тех случаях, когда в конфигурации используется подсистема «Обмен данными» БСП, и возникла необходимость отключить ее, следует устанавливать дополнительное свойство ОтключитьМеханизмРегистрацииОбъектов:

              \n

              Объект.ОбменДанными.Загрузка = Истина;
              Объект.ДополнительныеСвойства.Вставить(\"ОтключитьМеханизмРегистрацииОбъектов\");
              Объект.Записать();

              \n

              В случае других исключений, причина исключения из этого правила должна быть описана в комментарии к выполняемым действиям.

              \n

              3. Требования выше также распространяются на обработчики подписок на эти события.

              \n

              4. При этом вызывающая сторона, выставляя записываемому объекту признак ОбменДанными.Загрузка в Истина, берет на себя ответственность за целостность данных этого объекта.

              \n

              Например, при записи объекта через механизм обмена данными в РИБ это обеспечивается корректным состоянием объекта в том узле, где он был создан (или изменен).

              \n

              В других случаях вызывающая сторона должна принять меры по корректному заполнению записываемого объекта. Например, при загрузке данных через механизм обмена данными по правилам конвертации или с помощью формата EnterpriseData, следует выполнять все необходимые действия по (до)заполнению объекта. Эти действия рекомендуется размещать в экспортных процедурах самого объекта, которые используются вызывающей стороной при записи объекта в режиме обмена данными.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "76", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Неверно указана информация об авторских правах. Должно начинаться с \"Copyright © ООО \"1С-Софт\"\".", +"Description": "

              Заполнение свойств конфигурации информацией о выпуске

              #std482

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Синоним. В синониме указывается официальное название конфигурации, которое будет идентифицировать конфигурацию в документации, на коробке с продуктом, прайс-листе, рекламе, в информационных и методических материалах. В конце официального названия через запятую указывается слово \"редакция\" и номер редакции.

              \n

              Например: \"Бухгалтерия предприятия, редакция 1.6\"

              \n

              2. Имя. Имя образуется по правилам образования имен из синонима; слово \"редакция\", номер редакции (и подредакции) – не указываются.

              \n

              Например: \"БухгалтерияПредприятия\"

              \n

              3. Краткая информация. Краткая информация повторяет синоним.

              \n

              4. Подробная информация. Подробная информация повторяет синоним.

              \n

              5. Логотип. Для типовых конфигураций фирмы \"1С\" картинка логотипа не заполняется.

              \n

              6. Заставка. В качестве заставки устанавливается картинка одного из типов, поддерживаемых системой 1С:Предприятие. Требования к размеру картинки см. в документации.

              \n

              7. Авторские права. Указывается строка вида:

              \n

              Copyright (C) <разработчик>, хххх-хххх. Все права защищены.

              \n

              Для конфигураций на английском языке: Copyright (C) <разработчик>, хххх-хххх. All rights reserved.

              \n

              Вместо \"хххх-хххх\" указываются конкретные годы выпуска конфигурации.

              \n

              Например: Copyright (C) ООО \"1С-Софт\", 2009-2016. Все права защищены

              \n

              8. Адрес информации о поставщике. Для типовых конфигураций фирмы \"1С\" указывается строка:
              http://www.1c.ru

              \n

              9. Адрес информации о конфигурации. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              /\">http://v8.1c.ru/<короткое имя>/,

              \n

              где вместо <короткое имя> указывается англоязычное короткое имя конкретной конфигурации, например:

              \n

              http://v8.1c.ru/trade/

              \n

              10. Поставщик. Для типовых конфигураций фирмы \"1С\"  в качестве поставщика указывается:

              \n

              Фирма \"1С\"

              \n

              11. Версия. Указывается полный номер версии конфигурации. Например, 1.6.4.7

              \n

              Подробнее об образовании номера версии см. раздел Нумерация редакций и версий.

              \n

              12. Адрес каталога обновлений. Для типовых конфигураций фирмы \"1С\" указывается строка:

              \n

              http://downloads.v8.1c.ru/tmplts/

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "78", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Найдена экспортная процедура или функция в модуле формы.", +"Description": "

              Правила создания модулей форм

              #std630

              Область применения: управляемое приложение, мобильное приложение.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1. В модуле формы размещаются процедуры и функции, которые необходимы только для реализации логики работы этой формы и исполняются в контексте этой формы.

              \n

              1.1. Не следует размещать экспортные процедуры и функции в модулях форм. Для реализации экспортных процедур и функций рекомендуется использовать модули объектов, модули менеджеров объектов или общие модули. Для передачи входных параметров в формы следует применять метод ОткрытьФорму, для получения результата - процедуры-обработчики оповещений  (см. стандарт  Открытие форм), а для взаимодействия с открытыми формами - метод Оповестить и обработчик события ОбработкаОповещения (см. стандарт Обновление списков при интерактивных действиях пользователя).

              \n

              1.2. Неправильно использовать экспортные процедуры и функции формы для параметризации формы при открытии. Например, неправильно:

              \n

              Форма = ПолучитьФорму(\"ОбщаяФорма.МояФорма\");
              Форма.Открыть();
              Форма.УстановитьПараметрСПомощьюЭтойЭкспортнойФункции(РежимРаботы);

              \n

              правильно:

              \n

              ПараметрыФормы = Новый Структура(\"РежимРаботы\", РежимРаботы)
              ОткрытьФорму(\"ОбщаяФорма.МояФорма\", ПараметрыФормы)

              \n
              \n

              См. также: Открытие форм

              \n

              1.3. Также не следует вызывать экспортные процедуры и функции модуля формы для обновления данных формы или для программной перерисовки формы в результате действий пользователя в других формах. В этом случае следует использовать метод глобального контекста Оповестить, методы формы ОповеститьОЗаписиНового, ОповеститьОбАктивизации и ОповеститьОВыборе. См. также: Обновление списков при интерактивных действиях пользователя.

              \n

              1.4. Исключения из этого правила составляют экспортные процедуры-обработчики оповещений (ОписаниеОповещения.ИмяПроцедуры).

              \n

              2. В некоторых случаях в модуле формы возникает необходимость реализации процедур и функций, которые выполняются как на стороне клиента, так и на сервере. Например, для обновления данных формы из серверного обработчика ПриСозданииНаСервере и из клиентских событий ПриИзменении.

              \n

              Для того чтобы избежать дублирования кода, такие процедуры и функции необходимо размещать в модуле формы с директивой компиляции &НаКлиентеНаСервереБезКонтекста и передавать в них контекст самостоятельно в виде параметра. В качестве контекста может выступать либо сама форма (ФормаКлиентскогоПриложения), либо ее реквизит (ДанныеФормыСтруктура).

              \n

              Пример:

              \n

              &НаСервере
              Процедура ПриСозданииНаСервере()
               УстановитьДоступность(ЭтотОбъект);
              КонецПроцедуры

              \n

              &НаКлиенте
              Процедура РазрешитьРедактированиеСуммыПриИзменении(Элемент)
               УстановитьДоступность(ЭтотОбъект);
              КонецПроцедуры

              \n

              &НаКлиентеНаСервереБезКонтекста
              Процедура УстановитьДоступность(Форма)
               Форма.Элементы.ТоварыСумма.Доступность = Форма.Объект.РазрешитьРедактированиеСуммы;
              КонецПроцедуры

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "8", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Имя содержит букву \"ё\".", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n\n\n\n

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "80", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Общий модуль, доступный только на клиенте, должен именоваться с постфиксом \"Клиент\".", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "82", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не установлено свойство \"Использовать управляемые формы в обычном приложении\" для конфигурации.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "83", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Глобальный общий модуль должен именоваться с постфиксом \"Глобальный\".", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "84", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Привилегированный общий модуль должен именоваться с постфиксом \"ПолныеПрава\".", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "85", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Общий модуль с повторно используемыми значениями должен именоваться с постфиксом \"ПовтИсп\".", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "86", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не задан синоним стандартного реквизита \"Владелец\".", +"Description": "

              Имя, синоним, комментарий

              #std474

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n

              Данное требование продиктовано тем, что синонимы непосредственно участвуют в формировании пользовательского интерфейса (отображаются в формах, отчетах, командном интерфейсе и т.д.) и поэтому должны корректно и одинаково во всех местах пользовательского интерфейса идентифицировать ту сущность, к которой они относятся. Помимо объектов метаданных, требование распостраняется также и на реквизиты объектов метаданных, табличные части, реквизиты табличных частей, измерения регистров, ресурсы и другие объекты конфигурации, у которых имеется синоним.

              \n

              1.2. Не рекомендуется в синонимах объектов использовать сокращения. Исключением являются только общеупотребительные и соответствующие целевой аудитории сокращения (например, Сумма (регл.) ) и аббревиатуры (например, НДС или МСФО).

              \n

              1.3. В синонимах объектов и текстовых сообщениях пользователю должны использоваться общепринятые термины, понятные пользователю. Не должно быть сленга, искажения названий продуктов и компаний; англоязычных фраз, записанных русскими буквами; русскоязычных английскими буквами и т.п.

              \n

              В частности, если для англоязычного термина нет общепринятого перевода на русский язык, то следует использовать оригинальный англоязычный термин.
              Например, неправильно: «Загрузка данных из Эксель», «Загрузка данных из MS Excel»,
              правильно: «Загрузка данных из Microsoft Excel».

              \n

              1.4. В случае если у объекта метаданных имеются стандартные реквизиты (стандартные табличные части), для них также следует указывать синонимы, исходя из прикладного смысла каждого реквизита.

              \n

              1.5. При этом для стандартных реквизитов Родитель и Владелец, следует всегда указывать синонимы, отличные от синонимов по умолчанию. Например, в конфигурации имеется справочник Файлы со стандартным реквизитом Владелец типа СправочникСсылка.ПапкиФайлов. В этом случае
              неправильно

              \n
                \n
              • оставлять синоним стандартного реквизита Владелец по умолчанию: «Владелец»;
              \n

              правильно

              \n
                \n
              • вложить в синоним прикладной смысл: «Папка» или «Папка с файлом».
              \n

              Другой пример. В то время как для стандартного реквизита Наименование некоторых справочников может вполне подойти синоним по умолчанию «Наименование», в случае со справочником Файлы целесообразнее назначить синоним «Имя файла», а для справочника ФизическиеЛица – дать синоним «ФИО».

              \n
              \n

              См. также: Пользовательские представления объектов, Тексты

              \n

              1.6. В случае, когда есть два (или более) объекта метаданных со схожим назначением, необходимо, чтобы синонимы каждого объекта полностью описывали каждый объект.

              \n

              Например, неправильно давать справочникам следующие синонимы:

              \n
                \n
              • Банковские счета, \n
              • Банковские счета контрагентов
              \n

              правильно:

              \n
                \n
              • Банковские счета организаций, \n
              • и Банковские счета контрагентов
              \n

              Следует называть эти объекты явным образом, чтобы пользователь не задавался вопросом: «Если в справочнике Банковские счета контрагентов хранится информация о счетах контрагентов, то информация о чьих счетах хранится справочнике Банковские счета

              \n

              Это требование справедливо и для синонимов подчиненных объектов метаданных (реквизитов, табличных частей, измерений, ресурсов и пр.).
              Пример с реквизитами табличной части «Товары» документа «Пересчет товаров».
              Неправильно:

              \n
                \n
              • Количество \n
              • Количество (по учету)
              \n

              правильно:

              \n
                \n
              • Количество (в наличии) \n
              • Количество (по учету)
              \n

              Пример со стандартным реквизитом Наименование и еще одним реквизитом справочника «Номенклатура».
              Неправильно:

              \n
                \n
              • Наименование \n
              • Полное наименование
              \n

              правильно:

              \n
                \n
              • Рабочее наименование \n
              • Наименование для печати
              \n

              2.1. Имя объекта рекомендуется строить на основе синонима: пробелы и пр. недопустимые в имени символы, удаляются, а первые буквы слов делаются прописными.
              Например, неправильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Дополнительные свойства» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Файлы присоединенные»;
              \n

              правильно:

              \n
                \n
              • у справочника НаборыДополнительныхРеквизитовИСведений задан синоним «Наборы дополнительных реквизитов и сведений» \n
              • у общей команды ПрисоединенныеФайлы – синоним «Присоединенные файлы».
              \n

              Также допустимы ситуации, когда имя более кратко описывает объект, чем синоним – когда в имени «сокращены» одно или несколько последних «малозначащих» слов из синонима. Например:

              \n
                \n
              • ДлительностьОжиданияСервера – синоним «Длительность ожидания сервера (сек)» \n
              • КоличествоЕдиниц – синоним «Количество единиц измерения» \n
              • Обработки.ГрупповоеИзменениеОбъектов.Операции.ИмяРеквизита – синоним «Имя реквизита (свойство)»
              \n

              Имя также может не включать союзы и предлоги из текста синонима, например: для реквизита ЗначениеСкидкиНаценки синоним «Значение скидки или наценки».

              \n

              А также наоборот, допустимы ситуации, когда синоним более кратко описывает объект, чем имя – когда в синониме «сокращены» одно или несколько последних «технических» слов из имени.

              \n

              Данное требование продиктовано тем соображением, что объекты конфигурации и их представления в пользовательском интерфейсе должны быть максимально легко узнаваемыми, например, на внедрении, которое проводится не самими разработчиками конфигурации, а силами технических специалистов по внедрению.

              \n
              \n

              См. также: Дополнительные требования по именам объектов метаданных в конфигурациях

              \n

              2.2. Исключение из этого правила составляют объекты метаданных с префиксом Удалить.

              \n

              Также не следует переименовывать объекты метаданных (их реквизиты, формы и пр.) при пересмотре их синонимов, если на эти объекты распространяются требования обеспечения обратной совместимости. В частности, при разработке библиотек необходимо обеспечивать обратную совместимость между различными версиями библиотек в пределах одной редакции библиотеки.

              \n

              2.3. Имена объектов метаданных не должны превышать 80 символов.

              \n

              2.4. Для подчиненных объектов метаданных, таких как реквизиты, измерения, ресурсы рекомендуется не использовать имена, совпадающие с именами объектов-владельцев. Например, измерение Пользователь (типа СправочникСсылка.Пользователи) регистра сведений ИсполнителиЗадач названо некорректно; правильное название измерения, раскрывающее его смысл: Исполнитель.

              \n

              2.5. Также рекомендуется не использовать имена, которые применяются при именовании таблиц языка запросов (например, Документ, Справочник, РегистрСведений и т.д.). Такие имена могут приводить к ошибкам при исполнении запроса, затрудняют использование конструктора запроса и снижают наглядность текста запроса. Например, выполнение данного запроса вызывает ошибку:

              \n

              ВЫБРАТЬ
              Сведения.Сведения
              ИЗ
              РегистрСведений.Сведения КАК Сведения

              \n

              3.1. Комментарий задается только в тех случаях, когда необходимо дать участнику разработки конфигурации какие-либо пояснения по данному объекту конфигурации. Например, комментарий к реквизиту справочника может быть таким: \"Индексирование поставлено для оптимизации отчетов с отбором по виду контрагента\", или: \"Используется в регламентированном учете\".

              \n

              3.2. Комментарий начинается с прописной буквы, точки ставятся только после сокращений.

              4. В именах, синонимах и комментариях не допускается использовать букву \"ё\".

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": true, +"EffortMinutes": 0 +}, +{ +"Code": "87", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Орфографическая ошибка в подсказке объекта метаданных.", +"Description": "

              Общие требования к конфигурации

              #std467

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Конфигурация должна использовать только штатные и документированные возможности платформы 1С:Предприятие.

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              1.2. Конфигурация должна быть одинаково рассчитана на работу со всеми СУБД, операционными системами, веб-браузерами и различными режимами работы, которые поддерживает платформа 1С:Предприятие. В частности, в веб-клиенте все ключевые возможности конфигурации должны быть доступны пользователям без использования расширения работы с файлами, а взаимодействие с пользователем должно быть организовано асинхронно.
              Дополнительные материалы:

              \n\n

              1.3. Конфигурация не должна содержать ошибок, обнаруживаемых при проверке конфигурации (конфигуратор – меню КонфигурацияПроверка конфигурации…). Кроме отдельных, обоснованных случаев:

              \n\n

              1.4. Для поддержки обратной совместимости с различными собственными и сторонними решениями, внешними обработками и отчетами, разработанными на предыдущих версиях платформы 1С:Предприятие 8.0 и 8.1, конфигурация также должна поддерживать запуск в режимах обычного приложения (толстый клиент) и внешнего соединения для администраторов (пользователей с полными правами). Для этого рекомендуется 

              \n
                \n
              • свойство конфигурации «Использовать управляемые формы в обычном приложении» установить в Истина, а свойство «Использовать обычные формы в управляемом режиме» – в Ложь. \n
              • придерживаться общей схемы установки признаков общих модулей, \n
              • а саму разработку в Конфигураторе вести в режиме редактирования для обоих режимов запуска – управляемое и обычное приложение (меню СервисПараметры – закладка Общие).
              \n

              Отказ от поддержки запуска конфигурации в режимах обычного приложения и внешнего соединения для администраторов возможен только в отдельных, обоснованных случаях.

              \n

              1.5. При проектировании тех или иных технических решений, при разработке пользовательского интерфейса, отчетов и т.п. не рекомендуется отходить от умолчаний платформы 1С:Предприятие. Реализация альтернативных вариантов технических решений допустима только в отдельных, обоснованных случаях.

              \n

              2.1. Имена, синонимы, комментарии объектов метаданных, общих модулей, а также любая текстовая информация (которая выводится пользователю или предназначена для разработчика/внедренца) должны быть составлены по правилам русского языка и, в частности, не должны содержать грамматических ошибок.

              \n

              2.2. В конфигурации не должно быть неиспользуемых объектов метаданных (справочников, документов, разделов командного интерфейса и т.п.) и программного кода (общих модулей, процедур, функций, переменных и т.п.), который не используется ни в самой конфигурации, ни для интеграции с другими системами.

              \n

              2.3. Объекты метаданных верхнего уровня, такие как Справочники, Документы, Общие модули и т.д. рекомендуется сортировать в дереве метаданных по имени. Подчиненные объекты метаданных, такие как реквизиты, измерения, формы, располагаются в дереве метаданных в соответствии с проектной логикой.

              \n

              Исключение составляют:

              \n
                \n
              • общие реквизиты (т.к. для общих реквизитов, являющихся разделителями, порядок следования в дереве метаданных должен подбираться, исходя из требуемого порядка установки параметров сеанса). \n
              • объекты с префиксом \"Удалить\" (англ. \"Obsolete\"), которые допустимо размещать в конце соответствующей ветки метаданных;
              \n

               

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 5 +}, +{ +"Code": "89", +"Type": "CODE_SMELL", +"Severity": "INFO", +"Name": "Использован оператор \"Перейти\".", +"Description": "

              Ограничение на использование оператора Перейти

              #std547

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              1. В коде на встроенном языке не рекомендуется использовать оператор Перейти, так как необдуманное использование данного оператора приводит к получению запутанных, плохо структурированных модулей, по тексту которых затруднительно понять порядок исполнения и взаимозависимость фрагментов. Вместо оператора Перейти рекомендуется использовать другие конструкции встроенного языка. 

              \n

              Например, неправильно:

              \n

               Если ПланВидовРасчета = Объект.ПланВидовРасчета Тогда
                
                Перейти ~ПланВидовРасчета;
                
               КонецЕсли;

              \n

              правильно

              \n

               Если ПланВидовРасчета = Объект.ПланВидовРасчета Тогда
                
                ОбработатьПланВидовРасчета();
                
               КонецЕсли;

              \n\n\n\n
              \n
              \n

              Область применения (уточнение): управляемое приложение, обычное приложение.

              \n

              2. Запрещается использовать оператор Перейти в общих модулях с признаком \"Клиент (управляемое приложение)\", модулях команд и в клиентском коде модулей управляемых форм, так как данный метод не поддерживается платформой 1С:Предприятие в режиме веб-клиента.

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "90", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Общий модуль, для которого предусмотрен вызов сервера, должен именоваться с постфиксом \"ВызовСервера\".", +"Description": "

              Правила создания общих модулей

              #std469

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1.1. Общие модули создаются для реализации процедур и функций, объединенных по некоторому признаку. Как правило, в один общий модуль помещаются процедуры и функции одной подсистемы конфигурации (продажи, закупки) или процедуры и функции сходного функционального назначения (работа со строками, общего назначения).

              \n

              1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
              Тип общего модуляПример наименованияВызов сервераСерверВнешнее соединениеКлиент
              (обычное приложение)
              Клиент
              (управляемое приложение)
              1.СерверныйОбщегоНазначения (или ОбщегоНазначенияСервер)\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

               

              2.Серверный для вызова с клиентаОбщегоНазначенияВызовСервера\n

              +

              \n

              +

              \n

               

              \n

               

              3.КлиентскийОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)\n

               

              \n

               

              \n

               

              \n

              +

              \n

              +

              4.Клиент-серверныйОбщегоНазначенияКлиентСервер\n

               

              \n

              +

              \n

              +

              \n

              +

              \n

              +

              \n

              \n

              2.1. Серверные общие модули предназначены для размещения серверных процедур и функций, не доступных для использования из клиентского кода. В них реализуется вся внутренняя серверная бизнес-логика приложения.
              Для корректной работы конфигурации в режимах внешнего соединения, управляемого и обычного приложений, серверные процедуры и функции следует размещать в общих модулях с признаками:

              \n
                \n
              • Сервер (флажок Вызов сервера сброшен), \n
              • Клиент (обычное приложение), \n
              • Внешнее соединение
              \n

              В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект, ДокументОбъект и т.п.). Как правило, это:

              \n
                \n
              • обработчики подписок на события документов, справочников и т.п., которые принимают в качестве параметра мутабельное значение (объект).  \n
              • серверные процедуры и функции, в которые в качестве параметра передается объект из модулей справочников, документов и пр., а также из модулей с подписками на события.
              \n

              Серверные общие модули называются по общим правилам именования объектов метаданных.
              Например: РаботаСФайлами, ОбщегоНазначения

              \n

              В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс \"Сервер\" (англ. \"Server\").
              Например: РегламентныеЗаданияСервер, ОбменДаннымиСервер, ScheduledJobsServer.

              \n

              2.2. Серверные общие модули для вызова с клиента содержат серверные процедуры и функции, доступные для использования из клиентского кода. Они составляют клиентский программный интерфейс сервера приложения.
              Такие процедуры и функции размещаются в общих модулях с признаком:

              \n
                \n
              • Сервер (флажок Вызов сервера установлен)
              \n

              Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом \"ВызовСервера\" (англ. \"ServerCall\").
              Например: РаботаСФайламиВызовСервера, CommonServerCall

              \n

              Следует иметь в виду, что экспортные процедуры и функции в таких общих модулях не должны содержать параметров мутабельных типов (СправочникОбъект, ДокументОбъект и т.п.), так как их передача из (или в) клиентского кода невозможна.

              \n
              \n

              См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

              \n

              2.3. Клиентские общие модули содержат клиентскую бизнес-логику (функциональность, определенную только для клиента) и имеют признаки:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Клиент (обычное приложение)
              \n

              Исключение составляют случаи, когда клиентские процедуры и функции должны быть доступны только в режиме управляемого приложения (только в режиме обычного приложения или только в режиме внешнего соединения). В таких случаях, допустима иная комбинация двух этих признаков.

              \n

              Клиентские общие модули именуются с постфиксом \"Клиент\" (англ. \"Client\").
              Например: РаботаСФайламиКлиент, ОбщегоНазначенияКлиент, StandardSubsystemsClient

              \n
              \n

              См. также: минимизация кода, выполняемого на клиенте

              \n

              2.4. Для того чтобы избежать дублирования кода, рекомендуется создавать клиент-серверные общие модули с теми процедурами и функциями, содержание которых одинаково на сервере и на клиенте. Такие процедуры и функции размещаются в общих модулях с признаками:

              \n
                \n
              • Клиент (управляемое приложение) \n
              • Сервер (флажок Вызов сервера сброшен) \n
              • Клиент (обычное приложение) \n
              • Внешнее соединение
              \n

              Общие модули этого вида именуются с постфиксом \"КлиентСервер\" (англ. \"ClientServer\").
              Например: РаботаСФайламиКлиентСервер, ОбщегоНазначенияКлиентСервер, UsersClientServer

              \n

              В то же время, как только возникает необходимость ветвить код в клиент-серверных общих модулях на серверный и клиентский, то не следует использовать для этого инструкции препроцессора. Вместо этого, функциональность, различную для клиента и для сервера, рекомендуется реализовывать по общим правилам в модулях соответствующего типа – см. пп. 2.1 и 2.3. Такое явное разделение клиентской и серверной бизнес-логики продиктовано соображениями повышения модульности прикладного решения, упрощения контроля со стороны разработчика над клиент-серверным взаимодействием и снижением риска ошибок из-за принципиальных отличий требований к разработке клиентского и серверного кода (необходимость минимизации кода, выполняемого на клиенте, разной доступностью объектов и типов платформы и др.). При этом нужно иметь в виду неизбежное увеличение числа общих модулей в конфигурации.

              \n
              \n

              Подробнее см.: Использование директив компиляции и инструкций препроцессора

              \n

              Особым случаем смешанных клиент-серверных модулей являются модули форм и команд, которые специально предназначены для реализации серверной и клиентской бизнес-логики в одном модуле.

              \n

              3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как \"Процедуры\", \"Функции\", \"Обработчики\", \"Модуль\", \"Функциональность\" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

              \n

              Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.

              \n

              3.2. Дополнительно к общим модулям могут быть добавлены уточняющие постфиксы.

              \n

              3.2.1. Для глобальных модулей добавляется постфикс \"Глобальный\" (англ. \"Global\"), , в этом случае постфикс \"Клиент\" добавлять не следует.
              Например: РаботаСФайламиГлобальный, InfobaseUpdateGlobal

              \n

              3.2.2. Модули, выполняющиеся в привилегированном режиме, имеющие признак Привилегированный, именуются с постфиксом \"ПолныеПрава\" (англ. \"FullAccess\").
              Например: РаботаСФайламиПолныеПрава

              \n

              3.2.3. Модули, предназначенные для реализации на сервере или на клиенте функций с повторным использованием возвращаемых значений (на время вызова или на время сеанса), именуются с постфиксом \"ПовтИсп\" (англ. \"Cached\") и \"КлиентПовтИсп\" (англ. \"ClientCached\") соответственно.
              Например: РаботаСФайламиКлиентПовтИсп, UsersInternalCached

              \n

              3.2.4. Серверные и клиентские модули библиотечных конфигураций (которые предназначены не для самостоятельного использования, а для разработки других конфигураций) с процедурами и функциями, допускающие изменение своей реализации, именуются с постфиксами \"Переопределяемый\" (англ. \"Overridable\") и \"КлиентПереопределяемый\" (англ. \"ClientOverridable\").
              Например: РаботаСФайламиКлиентПереопределяемый, CommonOverridable

              \n
              \n

              См. также: Переопределяемые и поставляемые объекты библиотеки

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "93", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Не заполнено ни представление объекта, ни представление списка.", +"Description": "

              Пользовательские представления объектов

              #std468

              Область применения: управляемое приложение.

              \n

              Если для объекта метаданных определены свойства пользовательского представления, они заполняются следующим образом.

              1. Синоним объекта должен быть определен так, чтобы осмысленно, лаконично описывать объект. Заполняется обязательно.

              \n
              \n

              См. также: Имя, синоним, комментарий, Тексты

              \n

              2. Представление объекта (для регистра - представление записи). Задается название объекта в единственном числе, например, \"Валюта\". Название должно быть лаконичным и понятным. Например, вместо \"Версия проверяемой конфигурации\" нужно использовать \"Версия\".

              \n

              Представление объекта заполняется в случае, если синоним не может быть использован, как название объекта в единственном числе.

              3. Расширенное представление объекта (для регистра - расширенное представление записи). Задается полное название объекта в единственном числе. Заполняется в случае, когда название объекта, заданное в представлении объекта (или, если не заполнено, то - в синониме) менее информативно, чем его полное название. Например, в расширенном представлении объекта указано \"Реализация товаров и услуг\", в то время как в представлении объекта указано \"Реализация\".

              4. Представление списка. Задается название объектов во множественном числе, например, \"Валюты\". Кроме этого, в некоторых случаях может указываться название списка, если оно является самостоятельным термином, например, «Классификатор единиц измерения». Название должно быть лаконичным и понятным. Например, вместо \"Общероссийский классификатор основных фондов\" нужно использовать \"Классификатор ОКОФ\".

              \n

              Заполняется в случае, если синоним не может быть использован, как название списка объектов.

              5. Расширенное представление списка. Задается полное название списка объектов. Заполняется в случае, когда заданное в представлении списка (или, если не заполнено, то в синониме) название списка менее информативно, чем полное название списка.

              \n

              Например, в расширенном представлении списка указано \"Номенклатура (товары и услуги)\", представление списка не заполнено, а в синониме указано \"Номенклатура\".

              6. Расширенное представление. Задается полное название объекта метаданных. Заполняется в случае, когда заданное в синониме название объекта менее информативно, чем его полное название.

              \n

              Например, синоним обработки - \"Клиент банка\", а расширенное представление - \"Клиент банка (обмен платежными документами)\".

              7. Пояснение. Задается пояснение по назначению данного объекта метаданных. Пояснение задается в виде законченных предложений. Заполняется для объектов метаданных, представление которых не достаточно точно передает их назначение.

              \n

              Например, для справочника \"Организации\" пояснение может быть задано так: \"Юридические лица и предприниматели нашей компании.\".

              8. Картинка. Задается для подсистем верхнего уровня с установленным флажком \"Включать в командный интерфейс\". Размер картинки: 32 на 32.

              \n

              См. также

              \n", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "96", +"Type": "BUG", +"Severity": "CRITICAL", +"Name": "Использована конструкция \"ОБЪЕДИНИТЬ\".", +"Description": "

              Использование ключевых слов \"ОБЪЕДИНИТЬ\" и \"ОБЪЕДИНИТЬ ВСЕ\" в запросах

              #std434

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              В общем случае, при объединении в запросе результатов нескольких запросов следует использовать конструкцию ОБЪЕДИНИТЬ ВСЕ, а не ОБЪЕДИНИТЬ. Поскольку во втором варианте, при объединении запросов полностью одинаковые строки заменяются одной, на что затрачивается дополнительное время, даже в случаях, когда одинаковых строк в запросах заведомо быть не может.

              \n

              Исключением являются ситуации, когда выполнение замены нескольких одинаковых строк одной является необходимым условием выполнения запроса.

              Правильно:

              \n

              ВЫБРАТЬ
              ПоступлениеТоваровУслуг.Ссылка
              ИЗ
              Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

              ОБЪЕДИНИТЬ ВСЕ

              ВЫБРАТЬ
              РеализацияТоваровУслуг.Ссылка
              ИЗ
              Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

              \n

              Неправильно:

              \n

              ВЫБРАТЬ
              ПоступлениеТоваровУслуг.Ссылка
              ИЗ
              Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

              ОБЪЕДИНИТЬ

              ВЫБРАТЬ
              РеализацияТоваровУслуг.Ссылка
              ИЗ
              Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "98", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Использована конструкция Следующий() при проверке того, что результат выполнения запроса не содержит строк.", +"Description": "

              Проверка на пустой результат выполнения запроса

              #std438

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Проверку того, что результат выполнения запроса не содержит строк следует выполнять с помощью метода Пустой. Поскольку на получение выборки из результата запроса (выгрузка его в таблицу значений) будет затрачиваться дополнительное время.

              Неправильно:

              \n

              Выборка = Запрос.Выполнить().Выбрать();
              Если Выборка.Следующий() Тогда
                Возврат Истина;
              Иначе
                Возврат Ложь;
              КонецЕсли;

              \n

              Правильно:

              \n

              Возврат НЕ Запрос.Выполнить().Пустой()

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. В то же время если требуется выбрать (или выгрузить) результат запроса, то предварительный вызов метода Пустой не требуется.
              Например, вместо:

              \n

              РезультатЗапроса = Запрос.Выполнить();
              Если НЕ РезультатЗапроса.Пустой() Тогда // избыточный вызов
                Выборка = РезультатЗапроса.Выбрать(); 
                Пока Выборка.Следующий() Цикл
                ...

              \n

              правильно:

              \n

              Выборка = Запрос.Выполнить().Выбрать();
              Пока Выборка.Следующий() Цикл
              ...

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +}, +{ +"Code": "99", +"Type": "CODE_SMELL", +"Severity": "CRITICAL", +"Name": "Прикладной объект создан с помощью оператора Новый.", +"Description": "

              Программное создание прикладных объектов

              #std451

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Для программного создания прикладных объектов следует использовать методы соответствующих менеджеров (СоздатьЭлемент, СоздатьДокумент, СоздатьНаборЗаписей и т.д.).

              \n

              Для программного создания прикладных объектов, у которых существует соответствующие менеджеры объектов, использование конструктора (оператор встроенного языка Новый) запрещается.

              Правильно:

              \n

              ДокументПриходная = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();

              \n

              Неправильно:

              \n

              ДокументПриходная = Новый(\"ДокументОбъект.ПоступлениеТоваровУслуг\");

              \n

              2. При программном создании объекта следует явно вызывать метод объекта Заполнить. Если данных для заполнения нет, то передать значение Неопределено. В этом случае корректно отработают свойства реквизитов объекта \"Значение заполнения\", будет вызван обработчик ОбработкаЗаполнения и подписки на это событие, как при интерактивной работе с объектом.

              \n

              Например, неправильно:

              \n

              Папка = Справочники.ПапкиФайлов.СоздатьЭлемент();
              // ...
              Папка.Записать();

              \n

              Правильно:

              \n

              Папка = Справочники.ПапкиФайлов.СоздатьЭлемент();
              // ...
              Папка.Заполнить(Неопределено);
              // ...
              Папка.Записать();

              \n

              Исключением могут быть случаи, когда объект полностью загружается из источника при обмене данными или восстановление базы из резервной копии (загрузка из XML).

              ", +"Active": true, +"NeedForCertificate": false, +"EffortMinutes": 0 +} +] +} \ No newline at end of file diff --git a/src/main/resources/edt.json b/src/main/resources/edt.json new file mode 100644 index 00000000..28989c7b --- /dev/null +++ b/src/main/resources/edt.json @@ -0,0 +1,364 @@ +{ + "Rules": [ + { + "Code": "EDT-2", + "Name": "Возвращает тип, который имеет отличное окружение от контекста вызова", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 1 + }, + { + "Code": "EDT-3", + "Name": "Возможно, выражение не является объектом коллекции", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 1 + }, + { + "Code": "EDT-4", + "Name": "Возможно, недостижимое выражение", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-5", + "Name": "Неиспользуемая локальная переменная", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-6", + "Name": "Возможно, строковый литерал содержит ошибку", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "INFO", + "Active": true, + "EffortMinutes": 1 + }, + { + "Code": "EDT-7", + "Name": "Менеджер записи не может быть использован для регистра с режимом записи", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-8", + "Name": "Метод устарел", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-9", + "Name": "Неизвестное имя типа", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-10", + "Name": "Неиспользуемый локальный метод", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-11", + "Name": "Нельзя передавать объект типа между клиентом и сервером", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-12", + "Name": "Нельзя присваивать атрибуту формы значение типа", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-13", + "Name": "Нет соответствия между ожидаемыми типами", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 1 + }, + { + "Code": "EDT-14", + "Name": "Объект данного тип не может быть создан через оператор", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-15", + "Name": "Пустой метод модуля", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "INFO", + "Active": true, + "EffortMinutes": 1 + }, + { + "Code": "EDT-16", + "Name": "Свойство объекта не обнаружено", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-17", + "Name": "Свойство устарело", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-18", + "Name": "Тип устарел", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-19", + "Name": "Функция должна возвращать значение", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-20", + "Name": "Элемент с таким именем уже есть в глобальном контексте", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-21", + "Name": "Код никогда не будет скомпилирован", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-22", + "Name": "Недостаточное число параметров", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-23", + "Name": "Неизвестный оператор", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-24", + "Name": "Переменная не определена", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-25", + "Name": "Процедура или функция не определена", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-26", + "Name": "Свойство не предназначено для записи у типа", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-27", + "Name": "Синтаксическая ошибка. Неверный ввод - ожидается", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-28", + "Name": "Синтаксическая ошибка. Недопустимая лексема в данном контексте", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-29", + "Name": "Синтаксическая ошибка. Неизвестная лексема", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-30", + "Name": "Синтаксическая ошибка. Пропущена лексема y", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-31", + "Name": "Слишком много параметров", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-32", + "Name": "Слишком много параметров для типа(ов)", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-33", + "Name": "Тип неопределен", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-34", + "Name": "Функция не определена", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-35", + "Name": "Данный модуль не поддерживает данный тип директив компиляции", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 5 + }, + { + "Code": "EDT-36", + "Name": "Данный модуль может содержать только процедуры и функции", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-37", + "Name": "Недостаточное число параметров для типа(ов)", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-38", + "Name": "Оператор может использоваться только внутри процедур и функций", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-39", + "Name": "Процедура вызывается как функция", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-40", + "Name": "Синтаксическая ошибка. Неверная лексема - ожидается ", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-41", + "Name": "Синтаксическая ошибка. Пропущена лексема", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + } + ] +} diff --git a/src/main/resources/universal.json b/src/main/resources/universal.json new file mode 100644 index 00000000..ffd23e0d --- /dev/null +++ b/src/main/resources/universal.json @@ -0,0 +1,104 @@ +{ + "Rules": [ + { + "Code": "uni-1", + "Type": "BUG", + "Severity": "MINOR", + "Name": "Универсальная незначительная ошибка", + "Description": "

              Незначительная ошибка

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-2", + "Type": "BUG", + "Severity": "MAJOR", + "Name": "Универсальная важная ошибка", + "Description": "

              Важная ошибка

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-3", + "Type": "BUG", + "Severity": "CRITICAL", + "Name": "Универсальная критичная ошибка", + "Description": "

              Критичная ошибка

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-4", + "Type": "BUG", + "Severity": "BLOCKER", + "Name": "Универсальная блокирующая ошибка", + "Description": "

              Блокирующая ошибка

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-5", + "Type": "CODE_SMELL", + "Severity": "INFO", + "Name": "Универсальный информационный дефект кода", + "Description": "

              Информационный дефект кода

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-6", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Name": "Универсальный незначительный дефект кода", + "Description": "

              Незначительный дефект кода

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-7", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Name": "Универсальный важный дефект кода", + "Description": "

              Важный дефект кода

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-8", + "Type": "SECURITY_HOTSPOT", + "Severity": "CRITICAL", + "Name": "Универсальная потенциальная уязвимость", + "Description": "

              Потенциальная уязвимость

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-9", + "Type": "VULNERABILITY", + "Severity": "CRITICAL", + "Name": "Универсальная критичная уязвимость", + "Description": "

              Критичная уязвимость

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + }, + { + "Code": "uni-10", + "Type": "VULNERABILITY", + "Severity": "BLOCKER", + "Name": "Универсальная блокирующая уязвимость", + "Description": "

              Блокирующая уязвимость

              Универсальная диагностика

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 10 + } + ] +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensorTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensorTest.java index 2b800cfb..9aff2553 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensorTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLCoreSensorTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,11 +21,10 @@ */ package com.github._1c_syntax.bsl.sonar; -import com.github._1c_syntax.bsl.languageserver.configuration.DiagnosticLanguage; +import com.github._1c_syntax.bsl.languageserver.configuration.Language; import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; import org.junit.jupiter.api.Test; -import org.sonar.api.SonarRuntime; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; @@ -33,12 +32,15 @@ import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.internal.SonarRuntimeImpl; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.FileLinesContext; import org.sonar.api.measures.FileLinesContextFactory; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.Version; import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -47,18 +49,18 @@ class BSLCoreSensorTest { - private final String BASE_PATH = "src/test/resources/src"; + private final String BASE_PATH = "src/test/resources/examples"; private final File BASE_DIR = new File(BASE_PATH).getAbsoluteFile(); - private final String FILE_NAME = "test.bsl"; - final Version SONAR_VERSION = Version.create(7, 9); - private SensorContextTester context = SensorContextTester.create(BASE_DIR); + private final String FILE_NAME = "src/test.bsl"; + private final Version SONAR_VERSION = Version.create(7, 9); + private final SensorContextTester context = createSensorContext(); @Test void testDescriptor() { - FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); - BSLCoreSensor sensor = new BSLCoreSensor(context, fileLinesContextFactory); - DefaultSensorDescriptor sensorDescriptor = new DefaultSensorDescriptor(); + var sensor = new BSLCoreSensor(context, fileLinesContextFactory); + var sensorDescriptor = new DefaultSensorDescriptor(); sensor.describe(sensorDescriptor); assertThat(sensorDescriptor.name()).isEqualTo("BSL Core Sensor"); @@ -68,15 +70,15 @@ void testDescriptor() { @Test void testExecute() { - String diagnosticName = "OneStatementPerLine"; - RuleKey ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); + var diagnosticName = "OneStatementPerLine"; + var ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); SensorContextTester context; BSLCoreSensor sensor; // Mock visitor for metrics. - FileLinesContext fileLinesContext = mock(FileLinesContext.class); - FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class); + var fileLinesContext = mock(FileLinesContext.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); context = createSensorContext(); @@ -96,27 +98,50 @@ void testExecute() { context = createSensorContext(); setActiveRules(context, diagnosticName, ruleKey); - context.settings().setProperty(BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_KEY, DiagnosticLanguage.EN.getLanguageCode()); + context.settings().setProperty( + BSLCommunityProperties.LANG_SERVER_DIAGNOSTIC_LANGUAGE_KEY, Language.EN.getLanguageCode()); + sensor = new BSLCoreSensor(context, fileLinesContextFactory); + sensor.execute(context); + + assertThat(context.isCancelled()).isFalse(); + + context = createSensorContext(); + setActiveRules(context, diagnosticName, ruleKey); + context.settings().setProperty( + BSLCommunityProperties.LANG_SERVER_OVERRIDE_CONFIGURATION_KEY, Boolean.TRUE.toString()); + context.settings().setProperty( + BSLCommunityProperties.LANG_SERVER_CONFIGURATION_PATH_KEY, + Path.of(BASE_PATH, ".bsl-language-server.json").toString()); + sensor = new BSLCoreSensor(context, fileLinesContextFactory); + sensor.execute(context); + + assertThat(context.isCancelled()).isFalse(); + + context = createSensorContext(); + setActiveRules(context, diagnosticName, ruleKey); + context.settings().setProperty( + BSLCommunityProperties.LANG_SERVER_OVERRIDE_CONFIGURATION_KEY, Boolean.TRUE.toString()); + context.settings().setProperty(BSLCommunityProperties.LANG_SERVER_CONFIGURATION_PATH_KEY, "fake.file"); sensor = new BSLCoreSensor(context, fileLinesContextFactory); sensor.execute(context); assertThat(context.isCancelled()).isFalse(); - + } @Test void testExecuteCastDiagnosticParameterValue() { - String diagnosticEmptyCodeBlock = "EmptyCodeBlock"; - String diagnosticCommentedCode = "CommentedCode"; - String diagnosticLineLength = "LineLength"; - String diagnosticUsingHardcodeNetworkAddress = "UsingHardcodeNetworkAddress"; + var diagnosticEmptyCodeBlock = "EmptyCodeBlock"; + var diagnosticCommentedCode = "CommentedCode"; + var diagnosticLineLength = "LineLength"; + var diagnosticUsingHardcodeNetworkAddress = "UsingHardcodeNetworkAddress"; - FileLinesContext fileLinesContext = mock(FileLinesContext.class); - FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class); + var fileLinesContext = mock(FileLinesContext.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); - SensorContextTester context = createSensorContext(); + var context = createSensorContext(); ActiveRules activeRules = new ActiveRulesBuilder() .addRule(newActiveRule(diagnosticEmptyCodeBlock, "commentAsCode", "true")) .addRule(newActiveRule(diagnosticCommentedCode, "threshold", "0.9F")) @@ -129,7 +154,7 @@ void testExecuteCastDiagnosticParameterValue() { .build(); context.setActiveRules(activeRules); - BSLCoreSensor sensor = new BSLCoreSensor(context, fileLinesContextFactory); + var sensor = new BSLCoreSensor(context, fileLinesContextFactory); sensor.execute(context); assertThat(context.isCancelled()).isFalse(); @@ -137,20 +162,19 @@ void testExecuteCastDiagnosticParameterValue() { @Test void testExecuteCoverage() { - final String diagnosticName = "OneStatementPerLine"; - final RuleKey ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); + var diagnosticName = "OneStatementPerLine"; + var ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); SensorContextTester context; BSLCoreSensor sensor; // Mock visitor for metrics. - FileLinesContext fileLinesContext = mock(FileLinesContext.class); - FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class); + var fileLinesContext = mock(FileLinesContext.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); context = createSensorContext(); context.settings().setProperty(BSLCommunityProperties.LANG_SERVER_ENABLED_KEY, false); - context.settings().setProperty(BSLCommunityProperties.BSL_CALCULATE_LINE_TO_COVER_KEY, true); setActiveRules(context, diagnosticName, ruleKey); sensor = new BSLCoreSensor(context, fileLinesContextFactory); sensor.execute(context); @@ -158,8 +182,64 @@ void testExecuteCoverage() { assertThat(context.isCancelled()).isFalse(); } + @Test + void testComplexity() { + var diagnosticCyclomaticComplexity = "CyclomaticComplexity"; + var diagnosticCognitiveComplexity = "CognitiveComplexity"; + + var context = createSensorContext(); + var activeRules = new ActiveRulesBuilder() + .addRule(newActiveRule(diagnosticCyclomaticComplexity)) + .addRule(newActiveRule(diagnosticCognitiveComplexity)) + .build(); + context.setActiveRules(activeRules); + + var fileLinesContext = mock(FileLinesContext.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); + when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); + + BSLCoreSensor sensor = new BSLCoreSensor(context, fileLinesContextFactory); + + sensor.execute(context); + + // todo надо как-то нормально ключ компонента определить + var componentKey = "moduleKey:" + FILE_NAME; + assertThat(context.measures(componentKey)).isNotEmpty(); + assertThat(context.measure(componentKey, CoreMetrics.COMPLEXITY).value()).isEqualTo(3); + assertThat(context.measure(componentKey, CoreMetrics.COGNITIVE_COMPLEXITY).value()).isEqualTo(1); + + } + + @Test + void testCPD() { + var diagnosticName = "OneStatementPerLine"; + var ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); + + // Mock visitor for metrics. + var fileLinesContext = mock(FileLinesContext.class); + var fileLinesContextFactory = mock(FileLinesContextFactory.class); + when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext); + + var context = createSensorContext(); + + var sensor = new BSLCoreSensor(context, fileLinesContextFactory); + sensor.execute(context); + + var componentKey = "moduleKey:" + FILE_NAME; + assertThat(context.cpdTokens(componentKey)) + .isNotNull() + .hasSize(13); + assertThat(context.cpdTokens(componentKey)) + .filteredOn( tok -> tok.getValue().startsWith("ОставшийсяТокен")) + .hasSize(1); + assertThat(context.cpdTokens(componentKey)) + .filteredOn( tok -> tok.getValue().startsWith("ПропущенныйТокен")) + .isEmpty(); + + } + private void setActiveRules(SensorContextTester context, String diagnosticName, RuleKey ruleKey) { - ActiveRules activeRules = new ActiveRulesBuilder() + var activeRules = new ActiveRulesBuilder() .addRule(new NewActiveRule.Builder() .setRuleKey(ruleKey) .setName(diagnosticName) @@ -176,13 +256,22 @@ private NewActiveRule newActiveRule(String diagnosticName, String key, String va .build(); } + private NewActiveRule newActiveRule(String diagnosticName) { + return new NewActiveRule.Builder() + .setRuleKey(RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName)) + .setName(diagnosticName) + .build(); + } private SensorContextTester createSensorContext() { - SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarLint(SONAR_VERSION); - SensorContextTester context = SensorContextTester.create(BASE_DIR); + var sonarRuntime = SonarRuntimeImpl.forSonarLint(SONAR_VERSION); + var context = SensorContextTester.create(BASE_DIR); + context.fileSystem().setEncoding(StandardCharsets.UTF_8); context.setRuntime(sonarRuntime); + context.settings().setProperty("sonar.sources", "src"); + context.settings().setProperty("sonar.tests", "test"); - InputFile inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); + var inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); context.fileSystem().add(inputFile); return context; diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighterTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighterTest.java new file mode 100644 index 00000000..c8ba2e0f --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLHighlighterTest.java @@ -0,0 +1,508 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar; + +import com.github._1c_syntax.bsl.languageserver.BSLLSBinding; +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.parser.BSLLexer; +import com.github._1c_syntax.bsl.parser.SDBLLexer; +import com.github._1c_syntax.bsl.parser.SDBLTokenizer; +import org.antlr.v4.runtime.CommonToken; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.Vocabulary; +import org.junit.jupiter.api.Test; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.api.batch.sensor.internal.SensorContextTester; + +import java.io.File; +import java.net.URI; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class BSLHighlighterTest { + + private final String BASE_PATH = "src/test/resources/src"; + private final File BASE_DIR = new File(BASE_PATH).getAbsoluteFile(); + private final String FILE_NAME = "src/test.bsl"; + + private SensorContextTester context; + private BSLHighlighter highlighter; + private DocumentContext documentContext; + private InputFile inputFile; + + @Test + void testHighlightingBSL() { + + // given + var vocabulary = BSLLexer.VOCABULARY; + var highlightingMap = getHighlightingMapBSL(vocabulary); + + // then + testHighlighting(vocabulary, highlightingMap); + } + + @Test + void testHighlightingSDBL() { + // given + var vocabulary = SDBLLexer.VOCABULARY; + var highlightingMap = getHighlightingMapSDBL(vocabulary); + + // then + testHighlighting(vocabulary, highlightingMap); + } + + @Test + void testMergeHighlightingTokens() { + // given + context = SensorContextTester.create(Path.of(".")); + highlighter = new BSLHighlighter(context); + String content = "А = \"ВЫБРАТЬ РАЗРЕШЕННЫЕ Поле.Один \n" + + "|КАК \n" + + "| Один, 2 \n" + + " | КАК Два ИЗ Справочник.Поле\n" + + "|АВТОУПОРЯДОЧИВАНИЕ;\";"; + documentContext = BSLLSBinding.getServerContext().addDocument(URI.create("file:///fake.bsl"), content, 1); + + inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR, content); + + // when + highlighter.saveHighlighting(inputFile, documentContext); + + // then + var componentKey = "moduleKey:" + FILE_NAME; + + checkTokenTypeAtPosition(componentKey, 1, 4, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 1, 5, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 1, 6, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 1, 12, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 1, 13, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 1, 25, TypeOfText.STRING); + + checkTokenTypeAtPosition(componentKey, 2, 0, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 2, 1, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 2, 2, TypeOfText.KEYWORD); + + checkTokenTypeAtPosition(componentKey, 3, 0, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 3, 1, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 3, 5, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 3, 9, TypeOfText.CONSTANT); + + checkTokenTypeAtPosition(componentKey, 4, 1, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 4, 2, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 4, 6, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 4, 10, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 4, 13, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 4, 16, TypeOfText.KEYWORD_LIGHT); + + checkTokenTypeAtPosition(componentKey, 5, 0, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 5, 1, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 5, 18, TypeOfText.KEYWORD); + checkTokenTypeAtPosition(componentKey, 5, 19, TypeOfText.KEYWORD_LIGHT); + checkTokenTypeAtPosition(componentKey, 5, 20, TypeOfText.STRING); + checkTokenTypeAtPosition(componentKey, 5, 21, TypeOfText.KEYWORD_LIGHT); + + } + + private void testHighlighting(Vocabulary vocabulary, Map highlightingMap) { + // given + initContext(vocabulary); + + // when + highlighter.saveHighlighting(inputFile, documentContext); + + // then + checkHighlighting(vocabulary, context, highlightingMap); + } + + private void checkTokenTypeAtPosition(String componentKey, int line, int character, TypeOfText typeOfText) { + var typeOfTexts = context.highlightingTypeAt(componentKey, line, character); + assertThat(typeOfTexts) + .as("Position %d:%d should have typeOfText %s", line, character, typeOfText) + .contains(typeOfText); + } + + private void initContext(Vocabulary vocabulary) { + context = SensorContextTester.create(Path.of(".")); + highlighter = new BSLHighlighter(context); + documentContext = mock(DocumentContext.class); + List tokens = new ArrayList<>(); + + int maxTokenType = vocabulary.getMaxTokenType(); + for (var tokenType = 1; tokenType <= maxTokenType; tokenType++) { + var token = new CommonToken(tokenType, "a"); + token.setLine(1); + token.setCharPositionInLine(tokenType - 1); + tokens.add(token); + } + + var content = tokens.stream() + .map(Token::getText) + .collect(Collectors.joining()); + + if (vocabulary.equals(SDBLLexer.VOCABULARY)) { + var sdblTokenizer = mock(SDBLTokenizer.class); + when(sdblTokenizer.getTokens()).thenReturn(tokens); + when(documentContext.getQueries()).thenReturn(List.of(sdblTokenizer)); + } else { + when(documentContext.getTokens()).thenReturn(tokens); + } + inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR, content); + } + + private void checkHighlighting(Vocabulary vocabulary, + SensorContextTester context, + Map highlightingMap) { + var maxTokenType = vocabulary.getMaxTokenType(); + var componentKey = "moduleKey:" + FILE_NAME; + + assertThat(IntStream.range(1, maxTokenType)) + .isNotEmpty() + .allSatisfy(tokenType -> { + String symbolicTokenName = vocabulary.getSymbolicName(tokenType); + // no need to check lexer fragments or invisible names. + if (symbolicTokenName == null) { + return; + } + var typeOfText = highlightingMap.get(symbolicTokenName); + if (typeOfText == null) { + return; + } + + var typeOfTexts = context.highlightingTypeAt(componentKey, 1, tokenType - 1); + assertThat(typeOfTexts) + .as("Symbolic token name %s should maps to typeOfText %s", symbolicTokenName, typeOfText) + .contains(typeOfText); + }); + } + + private Map getHighlightingMapBSL(Vocabulary vocabulary) { + + Set literals = Set.of( + "TRUE", + "FALSE", + "UNDEFINED", + "NULL", + "DATETIME", + "DECIMAL", + "FLOAT" + ); + + Set punctuators = Set.of( + "SEMICOLON", + "QUESTION", + "PLUS", + "MINUS", + "MUL", + "QUOTIENT", + "MODULO", + "ASSIGN", + "LESS_OR_EQUAL", + "LESS", + "NOT_EQUAL", + "GREATER_OR_EQUAL", + "GREATER", + "COMMA", + "COLON", + "TILDA" + ); + + Set noOpTypes = Set.of( + "WHITE_SPACE", + "DOT", + "LBRACK", + "RBRACK", + "LPAREN", + "RPAREN", + "SQUOTE", + "IDENTIFIER", + "UNKNOWN", + "ANNOTATION_UNKNOWN", + "PREPROC_NEWLINE", + "BAR" + ); + + var maxTokenType = vocabulary.getMaxTokenType(); + + Map highlightingMap = new HashMap<>(); + for (int tokenType = 1; tokenType <= maxTokenType; tokenType++) { + var ruleName = vocabulary.getSymbolicName(tokenType); + // no need to check lexer fragments or invisible names. + if (ruleName == null) { + continue; + } + + TypeOfText typeOfText = null; + if (noOpTypes.contains(ruleName)) { + continue; + } else if (ruleName.endsWith("_KEYWORD") && !ruleName.startsWith("PREPROC_")) { + typeOfText = TypeOfText.KEYWORD; + } else if (literals.contains(ruleName)) { + typeOfText = TypeOfText.CONSTANT; + } else if (punctuators.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (ruleName.contains("STRING")) { + typeOfText = TypeOfText.STRING; + } else if (ruleName.contains("LINE_COMMENT")) { + typeOfText = TypeOfText.COMMENT; + } else if (ruleName.equals("AMPERSAND") || ruleName.contains("ANNOTATION_")) { + typeOfText = TypeOfText.ANNOTATION; + } else if (ruleName.equals("HASH") || ruleName.contains("PREPROC_")) { + typeOfText = TypeOfText.PREPROCESS_DIRECTIVE; + } + + if (typeOfText == null) { + throw new IllegalArgumentException("Unknown type of text for lexer rule name: " + ruleName); + } + + highlightingMap.put(ruleName, typeOfText); + } + return highlightingMap; + } + + private Map getHighlightingMapSDBL(Vocabulary vocabulary) { + + Set keywords = Set.of( + "ALL", + "ALLOWED", + "AND", + "AS", + "ASC", + "AUTOORDER", + "BETWEEN", + "BY_EN", + "CASE", + "CAST", + "DESC", + "DISTINCT", + "DROP", + "ELSE", + "END", + "ESCAPE", + "EMPTYREF", + "FALSE", + "FOR", + "FROM", + "FULL", + "GROUP", + "GROUPEDBY", + "GROUPING", + "HAVING", + "HIERARCHY", + "HIERARCHY_FOR_IN", + "IN", + "INDEX", + "INNER", + "INTO", + "IS", + "ISNULL", + "JOIN", + "LEFT", + "LIKE", + "NOT", + "OF", + "ON_EN", + "OR", + "ORDER", + "OVERALL", + "OUTER", + "PO_RU", + "RIGHT", + "SELECT", + "SET", + "THEN", + "TOP", + "TOTALS", + "UNION", + "WHEN", + "WHERE", + "ONLY", + "PERIODS", + "REFS", + "UPDATE" + ); + + Set functions = Set.of( + "AVG", + "BEGINOFPERIOD", + "BOOLEAN", + "COUNT", + "DATE", + "DATEADD", + "DATEDIFF", + "DATETIME", + "DAY", + "DAYOFYEAR", + "EMPTYTABLE", + "ENDOFPERIOD", + "HALFYEAR", + "HOUR", + "MAX", + "MIN", + "MINUTE", + "MONTH", + "NUMBER", + "QUARTER", + "PRESENTATION", + "RECORDAUTONUMBER", + "REFPRESENTATION", + "SECOND", + "STRING", + "SUBSTRING", + "SUM", + "TENDAYS", + "TYPE", + "VALUE", + "VALUETYPE", + "WEEK", + "WEEKDAY", + "YEAR" + ); + + Set metadataTypes = Set.of( + "ACCOUNTING_REGISTER_TYPE", + "ACCUMULATION_REGISTER_TYPE", + "BUSINESS_PROCESS_TYPE", + "CALCULATION_REGISTER_TYPE", + "CATALOG_TYPE", + "CHART_OF_ACCOUNTS_TYPE", + "CHART_OF_CALCULATION_TYPES_TYPE", + "CHART_OF_CHARACTERISTIC_TYPES_TYPE", + "CONSTANT_TYPE", + "DOCUMENT_TYPE", + "DOCUMENT_JOURNAL_TYPE", + "ENUM_TYPE", + "EXCHANGE_PLAN_TYPE", + "EXTERNAL_DATA_SOURCE_TYPE", + "FILTER_CRITERION_TYPE", + "INFORMATION_REGISTER_TYPE", + "SEQUENCE_TYPE", + "TASK_TYPE" + ); + + Set virtualTables = Set.of( + "ACTUAL_ACTION_PERIOD_VT", + "BALANCE_VT", + "BALANCE_AND_TURNOVERS_VT", + "BOUNDARIES_VT", + "DR_CR_TURNOVERS_VT", + "EXT_DIMENSIONS_VT", + "RECORDS_WITH_EXT_DIMENSIONS_VT", + "SCHEDULE_DATA_VT", + "SLICEFIRST_VT", + "SLICELAST_VT", + "TASK_BY_PERFORMER_VT", + "TURNOVERS_VT" + ); + + Set literals = Set.of( + "TRUE", + "FALSE", + "UNDEFINED", + "NULL", + "DECIMAL", + "FLOAT" + ); + + Set separators = Set.of( + "SEMICOLON", + "PLUS", + "MINUS", + "MUL", + "QUOTIENT", + "ASSIGN", + "LESS_OR_EQUAL", + "LESS", + "NOT_EQUAL", + "GREATER_OR_EQUAL", + "GREATER", + "COMMA", + "BRACE", + "BRACE_START" + ); + + Set noOpTypes = Set.of( + "WHITE_SPACE", + "DOT", + "LPAREN", + "RPAREN", + "ROUTEPOINT_FIELD", + "IDENTIFIER", + "INCORRECT_IDENTIFIER", + "BRACE_IDENTIFIER", + "UNKNOWN", + "BAR" // TODO: Убрать из лексера + ); + + var maxTokenType = vocabulary.getMaxTokenType(); + + Map highlightingMap = new HashMap<>(); + for (int tokenType = 1; tokenType <= maxTokenType; tokenType++) { + String ruleName = vocabulary.getSymbolicName(tokenType); + // no need to check lexer fragments or invisible names. + if (ruleName == null) { + continue; + } + + TypeOfText typeOfText = null; + if (noOpTypes.contains(ruleName)) { + continue; + } else if (keywords.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD; + } else if (literals.contains(ruleName)) { + typeOfText = TypeOfText.CONSTANT; + } else if (separators.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (functions.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (metadataTypes.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (virtualTables.contains(ruleName)) { + typeOfText = TypeOfText.KEYWORD_LIGHT; + } else if (ruleName.equals("STR")) { + typeOfText = TypeOfText.STRING; + } else if (ruleName.contains("LINE_COMMENT")) { + typeOfText = TypeOfText.COMMENT; + } else if (ruleName.equals("AMPERSAND") || ruleName.equals("PARAMETER_IDENTIFIER")) { + typeOfText = TypeOfText.ANNOTATION; + } + + if (typeOfText == null) { + throw new IllegalArgumentException("Unknown type of text for lexer rule name: " + ruleName); + } + + highlightingMap.put(ruleName, typeOfText); + } + return highlightingMap; + } + +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLPluginTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLPluginTest.java index 4aa669fd..22ca386d 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLPluginTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/BSLPluginTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -21,12 +21,17 @@ */ package com.github._1c_syntax.bsl.sonar; +import com.github._1c_syntax.bsl.sonar.ext_issues.AccReporter; +import com.github._1c_syntax.bsl.sonar.ext_issues.EdtReporter; +import com.github._1c_syntax.bsl.sonar.ext_issues.QualityProfilesContainer; +import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import com.github._1c_syntax.bsl.sonar.language.BSLQualityProfile; import org.junit.jupiter.api.Test; import org.sonar.api.Plugin; import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; -import org.sonar.api.SonarRuntime; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.internal.PluginContextImpl; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; import org.sonar.api.utils.Version; @@ -37,23 +42,43 @@ class BSLPluginTest { - private static final Version VERSION_7_9 = Version.create(7, 9); - private BSLPlugin bslPlugin = new BSLPlugin(); + private static final Version VERSION_8_9 = Version.create(8, 9); + private final BSLPlugin bslPlugin = new BSLPlugin(); @Test void testGetExtensions() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_7_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); - Plugin.Context context = new Plugin.Context(runtime); + var runtime = SonarRuntimeImpl.forSonarQube(VERSION_8_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); + var context = new Plugin.Context(runtime); bslPlugin.define(context); - assertThat((List) context.getExtensions()).hasSize(10); + assertThat((List) context.getExtensions()).hasSize(23); } @Test void testQualityProfile() { - BSLQualityProfile profile = new BSLQualityProfile(); - BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); + var profile = new BSLQualityProfile(); + var context = new BuiltInQualityProfilesDefinition.Context(); profile.define(context); - assertThat(context.profilesByLanguageAndName()).hasSize(1); + assertThat(context.profilesByLanguageAndName().get(BSLLanguage.KEY)).hasSize(1); + } + + @Test + void testQualityProfileAll() { + var runtime = SonarRuntimeImpl.forSonarQube(VERSION_8_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); + var config = new MapSettings() + .setProperty(AccReporter.create().getEnabledKey(), true) + .setProperty(EdtReporter.create().getEnabledKey(), true) + .asConfig(); + var context = new PluginContextImpl.Builder() + .setSonarRuntime(runtime) + .setBootConfiguration(config) + .build(); + + bslPlugin.define(context); + + var profile = new QualityProfilesContainer(config); + var contextProfile = new BuiltInQualityProfilesDefinition.Context(); + profile.define(contextProfile); + assertThat(contextProfile.profilesByLanguageAndName().get(BSLLanguage.KEY)).hasSize(5); } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/IssuesLoaderTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/IssuesLoaderTest.java index b4ff8120..d8c0799a 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/IssuesLoaderTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/IssuesLoaderTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -23,87 +23,165 @@ import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.DiagnosticRelatedInformation; import org.eclipse.lsp4j.DiagnosticSeverity; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; import org.junit.jupiter.api.Test; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultTextPointer; +import org.sonar.api.batch.fs.internal.DefaultTextRange; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.api.batch.sensor.issue.Issue; +import org.sonar.api.batch.sensor.issue.IssueLocation; import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.rule.RuleKey; import java.io.File; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class IssuesLoaderTest { - - private final String BASE_PATH = "src/test/resources/src"; - private final File BASE_DIR = new File(BASE_PATH).getAbsoluteFile(); - private final String FILE_NAME = "test.bsl"; - - @Test - public void test_createExtIssue() { - - final String issueCode = "Test"; - final DiagnosticSeverity issueSeverity = DiagnosticSeverity.Information; - - SensorContextTester context = SensorContextTester.create(BASE_DIR); - InputFile inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); - IssuesLoader issuesLoader = new IssuesLoader(context); - - Diagnostic diagnostic = new Diagnostic(); - diagnostic.setCode(issueCode); - diagnostic.setSeverity(issueSeverity); - diagnostic.setMessage("Check message"); - diagnostic.setRange(new Range(new Position(0, 0), new Position(0, 1))); - diagnostic.setRelatedInformation(null); - - issuesLoader.createIssue(inputFile, diagnostic); - - assertThat(context.allExternalIssues()).hasSize(1); - DefaultExternalIssue issue = (DefaultExternalIssue) context.allExternalIssues().toArray()[0]; - assertThat(issue.ruleId()).isEqualTo(issueCode); - - } - - @Test - public void test_createIssue() { - - final DiagnosticSeverity issueSeverity = DiagnosticSeverity.Information; - final String diagnosticName = "OneStatementPerLine"; - final RuleKey ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); - - SensorContextTester context = SensorContextTester.create(BASE_DIR); - - ActiveRules activeRules = new ActiveRulesBuilder() - .addRule(new NewActiveRule.Builder() - .setRuleKey(ruleKey) - .setName(diagnosticName) - .build()) - .build(); - context.setActiveRules(activeRules); - - InputFile inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); - context.fileSystem().add(inputFile); - - IssuesLoader issuesLoader = new IssuesLoader(context); - - Diagnostic diagnostic = new Diagnostic(); - diagnostic.setCode(diagnosticName); - diagnostic.setSeverity(issueSeverity); - diagnostic.setMessage("Check message OneStatementPerLine"); - diagnostic.setRange(new Range(new Position(0, 0), new Position(0, 1))); - - issuesLoader.createIssue(inputFile, diagnostic); - - assertThat(context.allIssues()).hasSize(1); - DefaultIssue issue = (DefaultIssue) context.allIssues().toArray()[0]; - assertThat(issue.ruleKey()).isEqualTo(ruleKey); - - } +class IssuesLoaderTest { + + private final String BASE_PATH = "src/test/resources/examples"; + private final File BASE_DIR = new File(BASE_PATH).getAbsoluteFile(); + private final String FILE_NAME = "src/test.bsl"; + + @Test + void test_createExtIssue() { + + var issueCode = "Test"; + var issueSeverity = DiagnosticSeverity.Information; + + var context = SensorContextTester.create(BASE_DIR); + var inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); + var issuesLoader = new IssuesLoader(context); + + var diagnostic = new Diagnostic(); + diagnostic.setCode(issueCode); + diagnostic.setSeverity(issueSeverity); + diagnostic.setMessage("Check message"); + diagnostic.setRange(new Range(new Position(0, 0), new Position(0, 1))); + diagnostic.setRelatedInformation(null); + + issuesLoader.createIssue(inputFile, diagnostic); + + assertThat(context.allExternalIssues()).hasSize(1); + var issue = (DefaultExternalIssue) context.allExternalIssues().toArray()[0]; + assertThat(issue.ruleId()).isEqualTo(issueCode); + + } + + @Test + void test_createIssue() { + + var issueSeverity = DiagnosticSeverity.Information; + var diagnosticName = "OneStatementPerLine"; + var ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); + + var context = SensorContextTester.create(BASE_DIR); + + var activeRules = new ActiveRulesBuilder() + .addRule(new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setName(diagnosticName) + .build()) + .build(); + context.setActiveRules(activeRules); + + var inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); + context.fileSystem().add(inputFile); + + var issuesLoader = new IssuesLoader(context); + + var diagnostic = new Diagnostic(); + diagnostic.setCode(diagnosticName); + diagnostic.setSeverity(issueSeverity); + diagnostic.setMessage("Check message OneStatementPerLine"); + diagnostic.setRange(new Range(new Position(0, 0), new Position(0, 1))); + + var uri = inputFile.uri().toString(); + var relatedInformation = List.of( + new DiagnosticRelatedInformation( + new Location(uri, new Range(new Position(11, 0), new Position(11, 8))), + "+1" + ), + new DiagnosticRelatedInformation( + new Location(uri, new Range(new Position(12, 0), new Position(12, 5))), + "+1" + ) + ); + diagnostic.setRelatedInformation(relatedInformation); + + issuesLoader.createIssue(inputFile, diagnostic); + + assertThat(context.allIssues()).hasSize(1); + DefaultIssue issue = (DefaultIssue) context.allIssues().toArray()[0]; + assertThat(issue.ruleKey()).isEqualTo(ruleKey); + assertThat(issue.flows()) + .hasSize(2) + .anySatisfy(flow -> assertThat(flow.locations()) + .hasSize(1) + .element(0) + .extracting(IssueLocation::textRange) + .isEqualTo(new DefaultTextRange(new DefaultTextPointer(12, 0), new DefaultTextPointer(12, 8))) + ) + .anySatisfy(flow -> assertThat(flow.locations()) + .hasSize(1) + .element(0) + .extracting(IssueLocation::textRange) + .isEqualTo(new DefaultTextRange(new DefaultTextPointer(13, 0), new DefaultTextPointer(13, 5))) + ) + ; + + } + + @Test + void issueWithIncorrectRange() { + // given + var issueSeverity = DiagnosticSeverity.Information; + var diagnosticName = "OneStatementPerLine"; + var ruleKey = RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, diagnosticName); + + var context = SensorContextTester.create(BASE_DIR); + + ActiveRules activeRules = new ActiveRulesBuilder() + .addRule(new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setName(diagnosticName) + .build()) + .build(); + context.setActiveRules(activeRules); + + var inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); + context.fileSystem().add(inputFile); + + var issuesLoader = new IssuesLoader(context); + + var diagnostic = new Diagnostic(); + diagnostic.setCode(diagnosticName); + diagnostic.setSeverity(issueSeverity); + diagnostic.setMessage("Check message OneStatementPerLine"); + + // when + diagnostic.setRange(new Range(new Position(3, 0), new Position(3, 25))); + + issuesLoader.createIssue(inputFile, diagnostic); + + // then + assertThat(context.allIssues()) + .hasSize(1) + .element(0) + .extracting(Issue::primaryLocation) + .extracting(IssueLocation::textRange) + .isEqualTo(new DefaultTextRange( + new DefaultTextPointer(4, 0), + new DefaultTextPointer(4, 0)) + ); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensorTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensorTest.java index 9ed9cbd7..ae2dcbd2 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensorTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/LanguageServerDiagnosticsLoaderSensorTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -23,9 +23,6 @@ import com.github._1c_syntax.bsl.sonar.language.BSLLanguageServerRuleDefinition; import org.junit.jupiter.api.Test; -import org.sonar.api.SonarRuntime; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; @@ -38,49 +35,48 @@ import static org.assertj.core.api.Assertions.assertThat; -public class LanguageServerDiagnosticsLoaderSensorTest { +class LanguageServerDiagnosticsLoaderSensorTest { - private final String BASE_PATH = "src/test/resources/src"; - private final File BASE_DIR = new File(BASE_PATH); - private final String FILE_NAME = "test.bsl"; + private final String BASE_PATH = "src/test/resources/examples"; + private final File BASE_DIR = new File(BASE_PATH); - @Test - public void test_describe() { + @Test + void test_describe() { - SensorContextTester context = SensorContextTester.create(BASE_DIR); - LanguageServerDiagnosticsLoaderSensor diagnosticsLoaderSensor = new LanguageServerDiagnosticsLoaderSensor(context); - DefaultSensorDescriptor sensorDescriptor = new DefaultSensorDescriptor(); - diagnosticsLoaderSensor.describe(sensorDescriptor); + var context = SensorContextTester.create(BASE_DIR); + var diagnosticsLoaderSensor = new LanguageServerDiagnosticsLoaderSensor(context); + var sensorDescriptor = new DefaultSensorDescriptor(); + diagnosticsLoaderSensor.describe(sensorDescriptor); - assertThat(sensorDescriptor.name()).containsIgnoringCase("BSL Language Server diagnostics loader"); - } + assertThat(sensorDescriptor.name()).containsIgnoringCase("BSL Language Server diagnostics loader"); + } - @Test - public void test_execute() { + @Test + void test_execute() { - InputFile inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); + var FILE_NAME = "src/test.bsl"; + var inputFile = Tools.inputFileBSL(FILE_NAME, BASE_DIR); - SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarLint(Version.create(7, 9)); - SensorContextTester context = SensorContextTester.create(BASE_DIR); - context.setRuntime(sonarRuntime); - context.settings().setProperty( - "sonar.bsl.languageserver.reportPaths", - "bsl-json.json, bsl-json2.json, empty.json, empty2.json"); - context.fileSystem().add(inputFile); + var sonarRuntime = SonarRuntimeImpl.forSonarLint(Version.create(7, 9)); + var context = SensorContextTester.create(BASE_DIR); + context.setRuntime(sonarRuntime); + context.settings().setProperty( + "sonar.bsl.languageserver.reportPaths", + "bsl-json.json, bsl-json2.json, empty.json, empty2.json"); + context.fileSystem().add(inputFile); - ActiveRules activeRules = new ActiveRulesBuilder() - .addRule(new NewActiveRule.Builder() - .setRuleKey(RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, "OneStatementPerLine")) - .setName("OneStatementPerLine") - .build()) - .build(); - context.setActiveRules(activeRules); + var activeRules = new ActiveRulesBuilder() + .addRule(new NewActiveRule.Builder() + .setRuleKey(RuleKey.of(BSLLanguageServerRuleDefinition.REPOSITORY_KEY, "OneStatementPerLine")) + .setName("OneStatementPerLine") + .build()) + .build(); + context.setActiveRules(activeRules); - LanguageServerDiagnosticsLoaderSensor diagnosticsLoaderSensor = new LanguageServerDiagnosticsLoaderSensor(context); - diagnosticsLoaderSensor.execute(context); + var diagnosticsLoaderSensor = new LanguageServerDiagnosticsLoaderSensor(context); + diagnosticsLoaderSensor.execute(context); - assertThat(context.isCancelled()).isFalse(); - - } + assertThat(context.isCancelled()).isFalse(); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/Tools.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/Tools.java index 46828354..02fb90d6 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/Tools.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/Tools.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -23,38 +23,36 @@ import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; public class Tools { - public static InputFile inputFileBSL(String name, File baseDir) { + public static InputFile inputFileBSL(String name, File baseDir, String content) { + return TestInputFileBuilder.create("moduleKey", name) + .setModuleBaseDir(baseDir.toPath()) + .setType(InputFile.Type.MAIN) + .setLanguage(BSLLanguage.KEY) + .setCharset(StandardCharsets.UTF_8) + .setContents(content) + .initMetadata(content) + .build(); + } - File file = new File(baseDir.getAbsoluteFile(), name); - String content; - try { - content = readFile(file.toPath().toString()); - } catch (IOException e) { - content = "Значение = 1; Значение2 = 1;"; - } + public static InputFile inputFileBSL(String name, File baseDir) { - DefaultInputFile inputFile = TestInputFileBuilder.create("moduleKey", name) - .setModuleBaseDir(baseDir.toPath()) - //.setCharset(StandardCharsets.UTF_8) - .setType(InputFile.Type.MAIN) - .setLanguage(BSLLanguage.KEY) - .initMetadata(content) - .build(); - return inputFile; + var file = new File(baseDir.getAbsoluteFile(), name); + String content; + try { + content = Files.readString(file.toPath(), StandardCharsets.UTF_8); + } catch (IOException e) { + content = "Значение = 1; Значение2 = 1;"; } - private static String readFile(String path) throws IOException { - byte[] encoded = Files.readAllBytes(Paths.get(path)); - return new String(encoded); - } + return inputFileBSL(name, baseDir, content); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReportersTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReportersTest.java new file mode 100644 index 00000000..d99fcc20 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/ExternalReportersTest.java @@ -0,0 +1,40 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import org.junit.jupiter.api.Test; +import org.reflections.Reflections; + +import static org.assertj.core.api.Assertions.assertThat; + +class ExternalReportersTest { + + @Test + void getReporters() { + var reporters = new Reflections(Reporter.class.getPackageName()) + .getSubTypesOf(Reporter.class); + + assertThat(ExternalReporters.REPORTERS) + .hasSize(reporters.size()) + .allMatch(reporter -> reporters.contains(reporter.getClass())); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfileTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfileTest.java new file mode 100644 index 00000000..840f1645 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/QualityProfileTest.java @@ -0,0 +1,77 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import com.github._1c_syntax.bsl.sonar.language.BSLLanguage; +import org.junit.jupiter.api.Test; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +class QualityProfileTest { + + private static final File BASE_DIR = new File("src/test/resources").getAbsoluteFile(); + private static final String ACC_TEST_RULES_FILE + = new File(BASE_DIR, "examples/acc-test.json").getAbsolutePath(); + private static final String ACC_TEST2_RULES_FILE + = new File(BASE_DIR, "examples/acc-test-second.json").getAbsolutePath(); + + @Test + void testQualityProfile() { + var config = new MapSettings() + .setProperty(AccReporter.create().getRulesPathsKey(), ACC_TEST_RULES_FILE + "," + ACC_TEST2_RULES_FILE) + .asConfig(); + var profile = new QualityProfilesContainer(config); + var context = new BuiltInQualityProfilesDefinition.Context(); + profile.define(context); + assertThat(context.profilesByLanguageAndName().get(BSLLanguage.KEY)).isNull(); + } + + @Test + void testQualityProfileEnabled() { + var properties = AccReporter.create(); + var config = new MapSettings() + .setProperty(properties.getEnabledKey(), true) + .setProperty(properties.getRulesPathsKey(), ACC_TEST_RULES_FILE + "," + ACC_TEST2_RULES_FILE) + .asConfig(); + var profile = new QualityProfilesContainer(config); + var context = new BuiltInQualityProfilesDefinition.Context(); + profile.define(context); + assertThat(context.profilesByLanguageAndName().get(BSLLanguage.KEY)).hasSize(3); + } + + @Test + void testQualityProfileEnabledWithoutFiles() { + var properties = AccReporter.create(); + var config = new MapSettings() + .setProperty(properties.getEnabledKey(), true) + .asConfig(); + var profile = new QualityProfilesContainer(config); + var context = new BuiltInQualityProfilesDefinition.Context(); + profile.define(context); + assertThat(context.profilesByLanguageAndName().get(BSLLanguage.KEY)).hasSize(3); + } + +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionTest.java new file mode 100644 index 00000000..1cae3928 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/ext_issues/RuleDefinitionTest.java @@ -0,0 +1,90 @@ +/* + * This file is a part of SonarQube 1C (BSL) Community Plugin. + * + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * SonarQube 1C (BSL) Community Plugin is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * SonarQube 1C (BSL) Community Plugin is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SonarQube 1C (BSL) Community Plugin. + */ +package com.github._1c_syntax.bsl.sonar.ext_issues; + +import org.junit.jupiter.api.Test; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.server.rule.RulesDefinition; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +class RuleDefinitionTest { + + private final Reporter reporter = EdtReporter.create(); + + @Test + void testDefine() { + + var config = new MapSettings() + .setProperty(reporter.getEnabledKey(), true) + .asConfig(); + var ruleDefinition = new RuleDefinitionsContainer(config); + var context = new RulesDefinition.Context(); + ruleDefinition.define(context); + + assertThat(context.repositories()).hasSize(1); + var repository = context.repository(reporter.getRepositoryKey()); + assertThat(repository).isNotNull(); + assertThat(repository.rules()).hasSize(40); + } + + @Test + void testEmptyExternalFilePath() { + var config = new MapSettings() + .setProperty(reporter.getEnabledKey(), true) + .setProperty(reporter.getRulesPathsKey(), "") + .asConfig(); + var ruleDefinition = new RuleDefinitionsContainer(config); + var context = new RulesDefinition.Context(); + ruleDefinition.define(context); + + assertThat(context.repositories()).hasSize(1); + var repository = context.repository(reporter.getRepositoryKey()); + assertThat(repository).isNotNull(); + assertThat(repository.rules()).hasSize(40); + } + + @Test + void testExternalFile() { + var baseDir = new File("src/test/resources").getAbsoluteFile(); + var fileRules = new File(baseDir, "examples/acc-test.json"); + var fileRulesSecond = new File(baseDir, "examples/acc-test-second.json"); + var fileRulesThird = new File(baseDir, "examples/edt-test.json"); + var config = new MapSettings() + .setProperty(reporter.getEnabledKey(), true) + .setProperty(reporter.getRulesPathsKey(), fileRules.getAbsolutePath() + + "," + fileRulesSecond.getAbsolutePath() + + "," + fileRulesThird.getAbsolutePath()) + .asConfig(); + var ruleDefinition = new RuleDefinitionsContainer(config); + var context = new RulesDefinition.Context(); + ruleDefinition.define(context); + + assertThat(context.repositories()).hasSize(1); + var repository = context.repository(reporter.getRepositoryKey()); + assertThat(repository).isNotNull(); + assertThat(repository.rules()).hasSize(44); + } + +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinitionTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinitionTest.java index 57b848b5..3fff54f4 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinitionTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageServerRuleDefinitionTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -22,23 +22,46 @@ package com.github._1c_syntax.bsl.sonar.language; import org.junit.jupiter.api.Test; -import org.sonar.api.config.Configuration; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.server.rule.RulesDefinition; +import java.util.Objects; + import static org.assertj.core.api.Assertions.assertThat; -public class BSLLanguageServerRuleDefinitionTest { +class BSLLanguageServerRuleDefinitionTest { + + @Test + void test_init() { + var config = new MapSettings().asConfig(); + var ruleDefinition = new BSLLanguageServerRuleDefinition(config); + var context = new RulesDefinition.Context(); + ruleDefinition.define(context); + + assertThat(context.repositories()).hasSize(1); + assertThat(context.repository(BSLLanguageServerRuleDefinition.REPOSITORY_KEY)).isNotNull(); + } - @Test - public void test_init() { - Configuration config = new MapSettings().asConfig(); - BSLLanguageServerRuleDefinition ruleDefinition = new BSLLanguageServerRuleDefinition(config); - RulesDefinition.Context context = new RulesDefinition.Context(); - ruleDefinition.define(context); + @Test + void testCheckTagParameters() { + var config = new MapSettings().asConfig(); + var ruleDefinition = new BSLLanguageServerRuleDefinition(config); + var context = new RulesDefinition.Context(); + ruleDefinition.define(context); - assertThat(context.repositories()).hasSize(1); - assertThat(context.repository(BSLLanguageServerRuleDefinition.REPOSITORY_KEY)).isNotNull(); - } + assertThat(context.repositories()).hasSize(1); + assertThat(Objects.requireNonNull(context.repository(BSLLanguageServerRuleDefinition.REPOSITORY_KEY)) + .rules().stream() + .filter(rule -> !rule.params().isEmpty()) + .filter(rule -> !rule.tags().contains(BSLLanguageServerRuleDefinition.PARAMETERS_TAG_NAME)) + .count() + ).isZero(); + assertThat(Objects.requireNonNull(context.repository(BSLLanguageServerRuleDefinition.REPOSITORY_KEY)) + .rules().stream() + .filter(rule -> rule.params().isEmpty()) + .filter(rule -> rule.tags().contains(BSLLanguageServerRuleDefinition.PARAMETERS_TAG_NAME)) + .count() + ).isZero(); + } } diff --git a/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageTest.java b/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageTest.java index dc11c04d..62ba2b7b 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/sonar/language/BSLLanguageTest.java @@ -1,8 +1,8 @@ /* * This file is a part of SonarQube 1C (BSL) Community Plugin. * - * Copyright © 2018-2020 - * Nikita Gryzlov + * Copyright (c) 2018-2022 + * Alexey Sosnoviy , Nikita Fedkin * * SPDX-License-Identifier: LGPL-3.0-or-later * @@ -27,22 +27,22 @@ import static org.assertj.core.api.Assertions.assertThat; -public class BSLLanguageTest { +class BSLLanguageTest { - @Test - public void test_create() { + @Test + void test_create() { - MapSettings settings = new MapSettings(); - settings.setProperty( - BSLCommunityProperties.BSL_FILE_EXTENSIONS_KEY, - BSLCommunityProperties.BSL_FILE_EXTENSIONS_DEFAULT_VALUE); + var settings = new MapSettings(); + settings.setProperty( + BSLCommunityProperties.BSL_FILE_EXTENSIONS_KEY, + BSLCommunityProperties.BSL_FILE_EXTENSIONS_DEFAULT_VALUE); - BSLLanguage language = new BSLLanguage(settings.asConfig()); + var language = new BSLLanguage(settings.asConfig()); - assertThat(language.getKey()).containsIgnoringCase("bsl"); - assertThat(language.getName()).containsIgnoringCase("1C (BSL)"); - assertThat(language.getFileSuffixes()).containsOnly(".bsl", ".os"); + assertThat(language.getKey()).containsIgnoringCase("bsl"); + assertThat(language.getName()).containsIgnoringCase("1C (BSL)"); + assertThat(language.getFileSuffixes()).containsOnly(".bsl", ".os"); - } + } } diff --git a/src/test/resources/examples/.bsl-language-server.json b/src/test/resources/examples/.bsl-language-server.json new file mode 100644 index 00000000..69a88e3b --- /dev/null +++ b/src/test/resources/examples/.bsl-language-server.json @@ -0,0 +1 @@ +{} diff --git a/src/test/resources/examples/acc-test-second.json b/src/test/resources/examples/acc-test-second.json new file mode 100644 index 00000000..5cae3d63 --- /dev/null +++ b/src/test/resources/examples/acc-test-second.json @@ -0,0 +1,24 @@ +{ + "Rules": [ + { + "Code": "2298", + "Type": "CODE_SMELL", + "Severity": "CRITICAL", + "Name": "Использована конструкция Следующий() при проверке того, что результат выполнения запроса не содержит строк.", + "Description": "

              Проверка на пустой результат выполнения запроса

              #std438

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Проверку того, что результат выполнения запроса не содержит строк следует выполнять с помощью метода Пустой. Поскольку на получение выборки из результата запроса (выгрузка его в таблицу значений) будет затрачиваться дополнительное время.

              Неправильно:

              \n

              Выборка = Запрос.Выполнить().Выбрать();
              Если Выборка.Следующий() Тогда
                Возврат Истина;
              Иначе
                Возврат Ложь;
              КонецЕсли;

              \n

              Правильно:

              \n

              Возврат НЕ Запрос.Выполнить().Пустой()

              \n\n\n\n
              \n

              Методическая рекомендация (полезный совет)

              \n

              2. В то же время если требуется выбрать (или выгрузить) результат запроса, то предварительный вызов метода Пустой не требуется.
              Например, вместо:

              \n

              РезультатЗапроса = Запрос.Выполнить();
              Если НЕ РезультатЗапроса.Пустой() Тогда // избыточный вызов
                Выборка = РезультатЗапроса.Выбрать(); 
                Пока Выборка.Следующий() Цикл
                ...

              \n

              правильно:

              \n

              Выборка = Запрос.Выполнить().Выбрать();
              Пока Выборка.Следующий() Цикл
              ...

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 0 + }, + { + "Code": "2299", + "Type": "CODE_SMELL", + "Severity": "CRITICAL", + "Name": "Прикладной объект создан с помощью оператора Новый.", + "Description": "

              Программное создание прикладных объектов

              #std451

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              1. Для программного создания прикладных объектов следует использовать методы соответствующих менеджеров (СоздатьЭлемент, СоздатьДокумент, СоздатьНаборЗаписей и т.д.).

              \n

              Для программного создания прикладных объектов, у которых существует соответствующие менеджеры объектов, использование конструктора (оператор встроенного языка Новый) запрещается.

              Правильно:

              \n

              ДокументПриходная = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();

              \n

              Неправильно:

              \n

              ДокументПриходная = Новый(\"ДокументОбъект.ПоступлениеТоваровУслуг\");

              \n

              2. При программном создании объекта следует явно вызывать метод объекта Заполнить. Если данных для заполнения нет, то передать значение Неопределено. В этом случае корректно отработают свойства реквизитов объекта \"Значение заполнения\", будет вызван обработчик ОбработкаЗаполнения и подписки на это событие, как при интерактивной работе с объектом.

              \n

              Например, неправильно:

              \n

              Папка = Справочники.ПапкиФайлов.СоздатьЭлемент();
              // ...
              Папка.Записать();

              \n

              Правильно:

              \n

              Папка = Справочники.ПапкиФайлов.СоздатьЭлемент();
              // ...
              Папка.Заполнить(Неопределено);
              // ...
              Папка.Записать();

              \n

              Исключением могут быть случаи, когда объект полностью загружается из источника при обмене данными или восстановление базы из резервной копии (загрузка из XML).

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 0 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/examples/acc-test.json b/src/test/resources/examples/acc-test.json new file mode 100644 index 00000000..a5533427 --- /dev/null +++ b/src/test/resources/examples/acc-test.json @@ -0,0 +1,14 @@ +{ + "Rules": [ + { + "Code": "96", + "Type": "BUG", + "Severity": "CRITICAL", + "Name": "Использована конструкция \"ОБЪЕДИНИТЬ\".", + "Description": "

              Использование ключевых слов \"ОБЪЕДИНИТЬ\" и \"ОБЪЕДИНИТЬ ВСЕ\" в запросах

              #std434

              Область применения: управляемое приложение, мобильное приложение, обычное приложение.

              \n

              В общем случае, при объединении в запросе результатов нескольких запросов следует использовать конструкцию ОБЪЕДИНИТЬ ВСЕ, а не ОБЪЕДИНИТЬ. Поскольку во втором варианте, при объединении запросов полностью одинаковые строки заменяются одной, на что затрачивается дополнительное время, даже в случаях, когда одинаковых строк в запросах заведомо быть не может.

              \n

              Исключением являются ситуации, когда выполнение замены нескольких одинаковых строк одной является необходимым условием выполнения запроса.

              Правильно:

              \n

              ВЫБРАТЬ
              ПоступлениеТоваровУслуг.Ссылка
              ИЗ
              Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

              ОБЪЕДИНИТЬ ВСЕ

              ВЫБРАТЬ
              РеализацияТоваровУслуг.Ссылка
              ИЗ
              Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

              \n

              Неправильно:

              \n

              ВЫБРАТЬ
              ПоступлениеТоваровУслуг.Ссылка
              ИЗ
              Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

              ОБЪЕДИНИТЬ

              ВЫБРАТЬ
              РеализацияТоваровУслуг.Ссылка
              ИЗ
              Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

              ", + "Active": true, + "NeedForCertificate": false, + "EffortMinutes": 0 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/src/bsl-json.json b/src/test/resources/examples/bsl-json.json similarity index 100% rename from src/test/resources/src/bsl-json.json rename to src/test/resources/examples/bsl-json.json diff --git a/src/test/resources/src/bsl-json2.json b/src/test/resources/examples/bsl-json2.json similarity index 100% rename from src/test/resources/src/bsl-json2.json rename to src/test/resources/examples/bsl-json2.json diff --git a/src/test/resources/examples/edt-test.json b/src/test/resources/examples/edt-test.json new file mode 100644 index 00000000..c1891814 --- /dev/null +++ b/src/test/resources/examples/edt-test.json @@ -0,0 +1,22 @@ +{ + "Rules": [ + { + "Code": "EDT-41", + "Name": "Синтаксическая ошибка. Пропущена лексема", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + }, + { + "Code": "EDT-99999", + "Name": "Синтаксическая ошибка", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "BLOCKER", + "Active": true, + "EffortMinutes": 10 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/src/empty2.json b/src/test/resources/examples/empty2.json similarity index 100% rename from src/test/resources/src/empty2.json rename to src/test/resources/examples/empty2.json diff --git a/src/test/resources/examples/src/test.bsl b/src/test/resources/examples/src/test.bsl new file mode 100644 index 00000000..275bc30d --- /dev/null +++ b/src/test/resources/examples/src/test.bsl @@ -0,0 +1,24 @@ +Функция Обработчик(Параметр1, Параметр2, Отказ, Параметр4) + Отказ = Истина; + Возврат А; Возврат А; + + Для Каждого Элемент Из Новый Массив Цикл + Сообщить("Да") + КонецЦикла; +КонецФункции + +&ИзменениеИКонтроль("Тест1") +Процедура рар_Тест1() + ПропущенныйТокен = а + 1; + #Вставка + ОставшийсяТокен = c + 1; + #КонецВставки +КонецПроцедуры + +#Область Тест + +Проверка = Истина; +Число = 0.01; +// Комментарий? + +#КонецОбласти \ No newline at end of file diff --git a/src/test/resources/src/test.bsl b/src/test/resources/examples/test/test.bsl similarity index 100% rename from src/test/resources/src/test.bsl rename to src/test/resources/examples/test/test.bsl