стандарт 723

ID: #std723

# Особенности разработки конфигураций для ОС Linux и macOS

#### 1.

В большинстве случаев платформа сама обеспечивает кроссплатформенную работу клиентского и серверного кода.

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

#### 2.

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

#### 2.1.

Вместо Windows-технологии COM (`COMОбъект`) используйте кроссплатформенные механизмы.

Например:

- для администрирования кластера вместо `v83.ComConnector` применяйте `ras`/`rac`;
- для путей к рабочим каталогам используйте `РабочийКаталогДанныхПользователя`, `КаталогДокументов`, `КаталогВременныхФайлов`.

#### 2.2.

Внешние компоненты, поставляемые с конфигурацией, разрабатывайте на технологии Native API.

Это обеспечивает поддержку Linux, macOS и веб-клиента.

#### 2.3.

Для механизмов, использующих объект `Почта`, рассмотрите переход на `ИнтернетПочта` или внешнюю компоненту с поддержкой почтовых клиентов Linux/macOS.

#### 2.4.

Если в составе конфигурации есть изображения WMF/EMF, замените их на PNG/JPG.

#### 2.5.

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

#### 2.5.1.

В Linux имена файлов регистрозависимы.
Указывайте пути в коде строго в одном регистре.

#### 2.5.2.

Не формируйте вручную разделители пути и маску всех файлов.
Используйте `ПолучитьРазделительПути` и `ПолучитьМаскуВсеФайлы`.

Если применяется БСП, используйте функции модулей `ОбщегоНазначения` и `ОбщегоНазначенияКлиент`.

#### 3.

Для второстепенных сервисных функций допустимо отключать функциональность в Linux/macOS.

Например, скрывать команду или выводить понятное сообщение, что операция доступна только в Windows.

#### Пример

```bsl
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    Информация = Новый СистемнаяИнформация;
    Если Информация.ТипПлатформы <> ТипПлатформы.Windows_x86
        И Информация.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
        ПоказатьПредупреждение(, НСтр("ru = 'Печать в Microsoft Word доступна только при работе в ОС Windows.'"));
        Возврат;
    КонецЕсли;

    ...
КонецПроцедуры
```

#### См. также

- [#std467: Общие требования к конфигурации](https://v8std.ru/std/467/)

#### Проверки

[#acc:1365](https://v8std.ru/diagnostics/acc/1365/)
[#acc:1366](https://v8std.ru/diagnostics/acc/1366/)
#### Источник

https://its.1c.ru/db/v8std#content:723

Разделитель пути файла указан вручную (необходимо использовать метод "ПолучитьРазделительПути()"). АПК:1365

Маска всех файлов указана вручную (необходимо использовать метод "ПолучитьМаскуВсеФайлы()"). АПК:1366

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

Особенности разработки конфигураций для ОС Linux и macOS #std723


стандарт 724

ID: #std724

# Использование модулей с повторным использованием возвращаемых значений

#### 1.

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

- на время сеанса;
- или на время вызова.

Используйте их для экономии вычислительных ресурсов сервера и для
[#std487: минимизации количества серверных вызовов и трафика](https://v8std.ru/std/487/)

#### См. также

- [Документация платформы: «Повторное использование возвращаемых значений»](https://its.1c.ru/db/v83doc/bookmark/dev/ti000000181)
- [Использование значений, влияющих на поведение клиентского приложения](https://its.1c.ru/bmk/std/common_values)

#### 2.

Чрезмерное применение модулей с повторным использованием возвращаемых значений
может приводить к [излишнему потреблению памяти](https://v8std.ru/std/725/)

#### 2.1.

Не кешируйте данные, которые вычисляются быстрее, чем извлекаются из кеша.

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

```bsl
Функция ИмяПакетаУправления() Экспорт
    Возврат "ManagementPackage";
КонецФункции
```

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

- из базы данных;
- из внешних источников;
- в результате ресурсоемких вычислений.

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

#### 2.2.

Помещайте в кеш только данные, к которым будут часто обращаться.

Учитывайте, что кеш не бессрочный:

- значение удаляется через `20` минут после вычисления;
- или через `6` минут после последнего использования,
  в зависимости от того, что наступит раньше;
- значение также удаляется при нехватке памяти, перезапуске рабочего процесса
  и переключении клиента на другой рабочий процесс.

Если закешированным значением никто не воспользовался,
ресурс потрачен впустую.

#### Примечание

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

#### 2.3.

Не делайте слишком широкий диапазон входных параметров у кешируемых функций.

#### Пример

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

При большом числе одновременных пользователей
такие «пустые» кеши создают заметные лишние расходы ресурсов.

#### 3.

Не изменяйте данные, полученные из кеша.

Иначе возникают скрытые ошибки и лишние расходы памяти.

В возвращаемых значениях используйте неизменяемые структуры данных,
например: `ФиксированныйМассив`, `ФиксированнаяСтруктура`.

Причина: кеш возвращает не копию, а ссылку на один и тот же объект в памяти.

#### 4.

Если в модуле с повторным использованием экспортные функции вызывают друг друга,
результат внутренних вызовов не кешируется.

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

```bsl
Функция АвтономнаяРаботаПоддерживается() Экспорт
    Возврат ...;
КонецФункции

Функция ЭтоАвтономноеРабочееМесто() Экспорт
    Возврат АвтономнаяРаботаПоддерживается() И ...;
КонецФункции
```

```bsl
... = ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается();
... = ОбменДаннымиПовтИсп.ЭтоАвтономноеРабочееМесто();
```

В этом сценарии `АвтономнаяРаботаПоддерживается` вычисляется дважды.

Чтобы получить значение из кеша, вызывайте функцию через имя модуля явно.

#### Правильно

```bsl
Функция ЭтоАвтономноеРабочееМесто() Экспорт
    Возврат ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается() И ...;
КонецФункции
```

#### 5.

Если у общего модуля свойство `Повторное использование возвращаемых значений`
установлено в `На время сеанса`,
не возвращайте из его функций значения типов:

- `МенеджерВременныхТаблиц`;
- `Запрос`;
- объекты базы данных (`ДокументОбъект`, `ОтчетОбъект` и т.п.);
- любые коллекции, которые содержат такие значения.

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

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

Ограничение также распространяется на использование таких значений
во временном хранилище.

#### См. также

- [#std470: Использование функциональных опций](https://v8std.ru/std/470/)
- [#std725: Оптимизация использования оперативной памяти](https://v8std.ru/std/725/)

#### Проверки

[#acc:435](https://v8std.ru/diagnostics/acc/435/)
[#acc:436](https://v8std.ru/diagnostics/acc/436/)
[#acc:437](https://v8std.ru/diagnostics/acc/437/)
[#acc:438](https://v8std.ru/diagnostics/acc/438/)
[#acc:439](https://v8std.ru/diagnostics/acc/439/)
[#acc:444](https://v8std.ru/diagnostics/acc/444/)
#### Источник

https://its.1c.ru/db/v8std#content:724

Возврат константы типа Строка в модуле с повторным использованием. АПК:435

Возврат константы типа Число в модуле с повторным использованием. АПК:436

Возврат константы типа Дата в модуле с повторным использованием. АПК:437

Возврат константы типа Булево в модуле с повторным использованием. АПК:438

Возврат предопределенного элемента в модуле с повторным использованием. АПК:439

Экспортная процедура в модуле с повторным использованием. АПК:444

Использование функциональных опций #std470

Минимизация количества серверных вызовов и трафика #std487

Оптимизация использования оперативной памяти #std725

Использование модулей с повторным использованием возвращаемых значений #std724


стандарт 725

ID: #std725

# Оптимизация использования оперативной памяти

#### Методическая рекомендация

Не проектируйте решение из предположения о неограниченной оперативной памяти.

#### 1.

Неэффективное использование памяти в многопользовательских системах быстро снижает стабильность работы.

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

#### 2.

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

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

Результат запроса целиком загружается в память:

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

// Выгрузка всего справочника в таблицу значений
Номенклатура = Запрос.Выполнить().Выгрузить();
Для Каждого ПозицияНоменклатуры Из Номенклатура Цикл
    // Обработка элемента справочника
КонецЦикла;
```

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

Неверно полагаться, что `Выбрать()` всегда решает проблему объема:

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

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Обработка элемента выборки
КонецЦикла;
```

#### Правильно

Используйте искусственное ограничение порции, например `ПЕРВЫЕ 1000`:

```bsl
Пока Истина Цикл

    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1000
        |   Номенклатура.Ссылка,
        |   Номенклатура.Наименование,
        |   Номенклатура.ВидНоменклатуры
        |ИЗ
        |   Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |   <условие выборки необработанных записей>";

    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
        Прервать;
    КонецЕсли;

    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        // Обработка элемента выборки
    КонецЦикла;

КонецЦикла;
```

#### Правильно

Допустим поэлементный обход через `Выбрать` объекта метаданных:

```bsl
Выборка = Справочники.Номенклатура.Выбрать(..., Отбор);
Пока Выборка.Следующий() Цикл
    // Обработка элемента выборки
КонецЦикла;
```

В этом случае платформа получает данные порциями фиксированного размера.

#### Примечание

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

#### 3.

Не обрабатывайте большие XML/HTML/текстовые файлы объектами,
которые загружают файл целиком в память:

- `ТекстовыйДокумент`;
- `ДокументDOM`;
- `ДокументHTML`;
- целиковая загрузка больших `XDTO`-пакетов.

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

Для экономного расхода памяти используйте потоковые объекты:

- `ЧтениеXML`, `ЧтениеТекста`;
- `ЗаписьXML`, `ЗаписьТекста`.

Для XDTO читайте файл последовательно через `ЧтениеXML`,
а отдельные фрагменты десериализуйте фабрикой XDTO.

#### 4.

Избегайте утечек памяти из-за циклических ссылок.

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

Упрощенный пример циклической ссылки:

```bsl
Данные = Новый Структура;
Данные.Вставить("Ключ", Данные);
```

#### Правильно

Разрывайте ссылку, когда объект больше не нужен:

```bsl
Данные.Ключ = Неопределено;
```

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

См. также:

- [Документация платформы: Приложение 3. Описание и расположение служебных файлов (`logcfg.xml`)](https://its.1c.ru/db/v83doc/content/27/hdoc)
- [Поиск циклических ссылок](https://its.1c.ru/db/metod8dev/content/5859)

#### 5.

Чрезмерное применение общих модулей с повторным использованием возвращаемых значений
тоже приводит к излишнему потреблению памяти.

#### См. также

- [#std724: Использование модулей с повторным использованием возвращаемых значений](https://v8std.ru/std/724/)

#### Источник

https://its.1c.ru/db/v8std#content:725


стандарт 726

ID: #std726

# Особенности использования в запросах оператора ПОДОБНО

#### 1.

Оператор `ПОДОБНО` в тексте запроса используйте только

- с константным строковым литералом, например:
`Реквизит ПОДОБНО "123%"`
- с параметром запроса, например:
`Реквизит ПОДОБНО &Шаблон`

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

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

```sdbl
Реквизит ПОДОБНО "123" + "%"
Реквизит ПОДОБНО &Шаблон + "%"
Реквизит ПОДОБНО Таблица.Шаблон
```

#### Правильно

```sdbl
Реквизит ПОДОБНО "123%"
Реквизит ПОДОБНО &Шаблон
```

#### В стандарте не указано

PostgreSQL и Oracle Database:

Квадратные скобки `[…]` в шаблоне работают как спецсимволы в строковом литерале, и не работают в выражении.

```sdbl
ВЫБРАТЬ * Справочник.Товары ГДЕ Артикул ПОДОБНО "123[АБ]%"
```

```sdbl
ВЫБРАТЬ * Справочник.Товары ГДЕ Артикул ПОДОБНО &Шаблон + "%"
```

```sdbl
ВЫБРАТЬ * Справочник.Товары ГДЕ Артикул ПОДОБНО &Шаблон
```

- [Приложение 8. Особенности работы с различными СУБД](https://its.1c.ru/db/v851doc#bookmark:dev:TI000001291)

#### 2.

Используйте такие шаблоны оператора `ПОДОБНО`, которые работают одинаково на всех поддерживаемых СУБД.

Допустимо:

- `%` (процент) – последовательность, содержащая любое количество произвольных символов;
- `_` (подчеркивание) – один произвольный символ.

Не работает в IBM DB2:

- `[…]` (в квадратных скобках один или несколько символов) – любой одиночный символ из перечисленных внутри квадратных скобок. В перечислении могут встречаться диапазоны, например `[a-z]`, означающие произвольный символ, входящий в диапазон, включая концы диапазона;
- `[^…]` (в квадратных скобках значок отрицания, за которым следует один или несколько символов) – любой одиночный символ, кроме тех, которые перечислены следом за значком отрицания.

Ограничение в MS SQL 2005:

- Длина строки шаблона не должна превышать `1024` символа

#### 3.

В шаблонах подобия используются спецсимволы `_%[]^`.
Шаблоны подобия могут формироваться динамически, по введенным данным пользователя.
В введенных пользователю данных могут использоваться спецсимволы, которые необходимо трактовать как данные пользователя. Для того, чтобы спецсимвол трактовался как обычный символ его необходимо экранировать.

#### Например

Пользователь вводит текст: `Кефир 15% жирности`.
Программа должны этот `%` трактовать как часть строки, а не как спецсимвол последовательности произвольных символов.

#### Ошибка

При работе на PostgreSQL можно встретить ошибку
`ERROR:  invalid regular expression: invalid character range` при выполнении запроса с некорректно собранным фрагментом содержащим `[]`.

Для экранирования:

- выберите спецсимвол экранирования, например `~`;
- установите спецсимвол перед символами операнда, например `~%`. Чтобы экранировать выбранный спецсимвол, его необходимо задвоить, например `~~`.
- дополните шаблон ключевым словом `СПЕЦСИМВОЛ`.

#### Например

Для поиск по строке `100%`
```sdbl
"100~%" СПЕЦСИМВОЛ "~"
```

Для поиск по строке `Кефир 15% жирности`
```sdbl
"Кефир 15~% жирности" СПЕЦСИМВОЛ "~"
```

Для поиск по строке `Шуруп_10[21] медь~4%`
```sdbl
"Шуруп~_10~[21~] медь~~4~%" СПЕЦСИМВОЛ "~"
```

Установка параметров запроса с помощью `Запрос.УстановитьПараметр()` не экранирует спецсимволы шаблона подобия.

Для экранирования используйте функцию `СформироватьСтрокуДляПоискаВЗапросе()`

#### Например

```sdbl
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"
```

```bsl
Запрос.УстановитьПараметр("Шаблон", "%" + ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(ИскомыйТекст) + "%");
```

#### Паттерн

```bsl
Функция СформироватьСтрокуДляПоискаВЗапросе(Знач СтрокаПоиска) Экспорт

    Результат = СтрокаПоиска;
    Результат = СтрЗаменить(Результат, "~", "~~");
    Результат = СтрЗаменить(Результат, "%", "~%");
    Результат = СтрЗаменить(Результат, "_", "~_");
    Результат = СтрЗаменить(Результат, "[", "~[");
    Результат = СтрЗаменить(Результат, "]", "~]");
    Результат = СтрЗаменить(Результат, "^", "~^");

    Возврат Результат;

КонецФункции
```

В 1С:БСП реализован в `ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе()`.

#### 4.

Сравнение выполняется без учета регистра символов.

#### Проверки
[#bslls:UsingLikeInQuery](https://v8std.ru/diagnostics/bslls/UsingLikeInQuery/)
[#v8cs:ql-constants-in-binary-operation](https://v8std.ru/diagnostics/v8-code-style/ql-constants-in-binary-operation/)

#### Источник

https://its.1c.ru/db/v8std#content:726

Оператор ПОДОБНО в тексте запроса используйте только

Использование 'ПОДОБНО' в запросе BSLLS:UsingLikeInQuery

В запросе в бинарной операции используются константные значения или параметры. (ql-constants-in-binary-operation)

Особенности использования в запросах оператора ПОДОБНО #std726


стандарт 728

ID: #std728

# Ограничения на использование реквизитов составного типа

#### 1.1.

Если реквизит составного типа используется в соединениях, отборах или сортировке, оставляйте в его составе только ссылочные типы:
`СправочникСсылка.[…]`, `ДокументСсылка.[…]` и т. п.

Не включайте в такой составной тип нессылочные значения:
`Строка`, `Число`, `Дата`, `УникальныйИдентификатор`, `Булево`, `ХранилищеЗначения`.

Иначе производительность запросов заметно снижается из-за особенностей физического хранения составных типов в таблицах СУБД.
Подробности: [Особенности хранения составных типов данных](https://its.1c.ru/db/metod81/content/1828/hdoc).

#### 1.2.

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

Пример: в документе есть реквизит `Адрес` составного типа, который включает ссылку на справочник `Контакты` и `Строку`.
Вместо этого создайте отдельный справочник `ПроизвольныеАдреса` и включите его в тип реквизита `Адрес` вместо строки.

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

#### 1.3.

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

#### 2.1.

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

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

Проблемы избыточно широких составных типов:

- при обращении «через точку» к реквизиту такого типа без `ВЫРАЗИТЬ` выполняется неявное соединение со всеми таблицами из состава типа, что существенно ухудшает производительность;
- возникают лишние реструктуризации при удалении ссылочных объектов метаданных (например, значений перечислений или точек маршрута бизнес-процесса, которые тоже входят в `ЛюбаяСсылка`);
- неоправданно усложняются алгоритмы, которые начинают поддерживать широкий набор типов, не нужный для прикладной задачи;
- сложнее анализировать работу механизма внедренцам и сторонним разработчикам;
- пользователю неудобно выбирать значение в форме из слишком большого списка типов (когда реально нужно 3-5 типов);
- при удалении помеченных объектов растут издержки анализа и блокировок таблиц при поиске ссылок.

#### 2.2.

Если составной тип массово используется в объектах подсистемы или всей конфигурации, применяйте [#std704: определяемые типы](https://v8std.ru/std/704/)

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

#### См. также

- [#std654: Разыменование ссылочных полей составного типа в языке запросов](https://v8std.ru/std/654/)

#### Проверки
[#v8cs:db-object-anyref-type](https://v8std.ru/diagnostics/v8-code-style/db-object-anyref-type/)
[#v8cs:db-object-ref-non-ref-type](https://v8std.ru/diagnostics/v8-code-style/db-object-ref-non-ref-type/)

[#acc:1329](https://v8std.ru/diagnostics/acc/1329/)
[#acc:1330](https://v8std.ru/diagnostics/acc/1330/)
#### Источник

https://its.1c.ru/db/v8std#content:728

Если реквизит составного типа используется в соединениях, отборах или сортировке, оставляйте в его составе только ссылочные типы: СправочникСсылка.[…], ДокументСсылка.[…] и т. п.

Недопустимое одновременное использование ссылочных и нессылочных типов в составном типе. АПК:1329

Недопустимое использование универсального составного типа (ЛюбаяСсылка, СправочникСсылка и т.п.). АПК:1330

Реквизиты составного типа, такие как ЛюбаяСсылка и аналогичные (db-object-anyref-type)

Реквизиты составного типа (db-object-ref-non-ref-type)

Разыменование ссылочных полей составного типа в языке запросов #std654

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

Ограничения на использование реквизитов составного типа #std728


стандарт 729

ID: #std729

# Общие требования по разработке оптимальных запросов

Прежде чем переходить к продвинутым приемам оптимизации, убедитесь, что сам запрос адекватен задаче.

#### 1.1.

Минимизируйте объем выборки: выбирайте только данные, необходимые для решения задачи.

Если нужны конкретные поля, не используйте `ВЫБРАТЬ *`.

Если нужно выполнять свертку, сортировку или вычисления, сначала проверьте, можно ли переложить эти операции на СУБД и сразу получить готовый результат.

#### 1.2.

В большинстве случаев следует минимизировать и общее количество запросов к СУБД.

#### См. также

[#std436: Многократное выполнение однотипных запросов](https://v8std.ru/std/436/)

#### 2.

Не следует любой ценой переносить выполнение задачи в СУБД: простые запросы СУБД обычно выполняет эффективнее, чем избыточно сложные универсальные.

#### 2.1.

Рассматривайте альтернативы:

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

#### 2.2.

Для сложных запросов проверяйте, что СУБД выбирает эффективный план выполнения.

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

В первую очередь:

- не добавляйте [#std655: вложенные запросы](https://v8std.ru/std/655/) только ради читаемости
- избегайте сложных условий в `ПО` и `ГДЕ`, особенно с [#std656: подзапросами в условиях соединения](https://v8std.ru/std/656/) и конструкцией `ВЫБОР`
- используйте минимально необходимое число таблиц в запросе.

План выполнения можно смотреть через консоль запросов, технологический журнал или средства СУБД. Признак проблемного сложного запроса: в плане присутствует `timeout warning` — оптимизатору не хватило времени выбрать лучший план.

См. также:.

#### Источник

https://its.1c.ru/db/v8std#content:729

Многократное выполнение однотипных запросов #std436

Ограничения на соединения с вложенными запросами и виртуальными таблицами #std655

Ограничения на использование вложенных запросов в условии соединения #std656

Общие требования по разработке оптимальных запросов #std729


стандарт 731

ID: #std731

# Требования к установке и обновлению прикладных решений

#### 1.

Подготовка дистрибутивов установки и обновления прикладных решений (конфигураций) системы 1С:Предприятие 8 должна выполняться в соответствии с рекомендациями, изложенными в [главе 30 «Поставка и поддержка конфигурации»](https://its.1c.ru/db/v83doc/content/88/hdoc) Руководства разработчика из комплекта документации к программным продуктам системы 1С:Предприятие 8.

#### 2.

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

```cmd
<Каталог шаблонов>\<каталог разработчика>\<каталог конфигурации>\<каталог версии>
```

При этом в каталоге версии вместо точек должны использоваться подчеркивания.
Например, версия 11.1.3.6 конфигурации «Управление торговлей», редакция 11.1, будет устанавливаться в каталог:

```cmd
<Каталог шаблонов>\1C\Trade\11_1_3_6\
```

#### 3.

В каталоге версии должен быть расположен `файл-манифест 1cv8.mft`, в котором описываются установленные `шаблоны конфигурации (.cf)` и `демонстрационные информационные базы (.dt)`.
Например, файл-манифест конфигурации «Управление торговлей», редакция 11.1, при установке которой устанавливаются 2 шаблона информационных баз - пустой (рабочей) и демонстрационной базы.

```ini
Vendor=Фирма "1С"
Name=УправлениеТорговлей
Version=11.1.3.6
AppVersion=8.3
[Config1]
Catalog=1С:Управление торговлей/Управление торговлей
Destination=1C\Trade
Source=1cv8.cf
[Config2]
Catalog=1С:Управление торговлей/Управление торговлей (демо)
Destination=1C\DemoTrd
Source=1Cv8.dt
```

#### 4.1.

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

- В строке **Catalog** файла-манифеста, в наименование шаблона конфигурации (часть значения до символа «/») следует включать в явном виде название разработчика. Название разработчика может присутствовать в любом месте наименования шаблона конфигурации, например:
  - **1С:Управление торговлей**
  - **Управление торговлей (1С)**
- В строке **Destination** рекомендуемый каталог создания информационной базы следует указывать в виде:

```ini
Destination = <каталог разработчика>\<каталог информационной базы>
```

** должен содержать название разработчика, но в этом случае - адаптированное для использования в именах файловых каталогов.
Например: 1C\Trade

#### 4.2.

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

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

#### 5.

Для обновления версий прикладных решений (конфигураций) выпускаются отдельные дистрибутивы обновлений, которые включают в себя файл обновления конфигурации (.cfu).

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

#### Источник

https://its.1c.ru/db/v8std#content:731

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

Требования к установке и обновлению прикладных решений #std731


стандарт 733

ID: #std733

# Эффективное обращение к виртуальной таблице «Остатки»

Эта рекомендация дополняет [#std657: Обращения к виртуальным таблицам](https://v8std.ru/std/657/) и описывает практики для виртуальной таблицы `Остатки` регистров накопления и бухгалтерии

При обращении к виртуальной таблице платформа формирует вложенный SQL-запрос.
Самый эффективный вариант — чтение хранимой таблицы текущих остатков без группировки по измерениям.

Чтобы платформа построила такой вариант, одновременно выполняйте условия:

- получайте остатки без указания даты;
- не используйте режим разделения итогов;
- во внешнем запросе используйте все измерения виртуальной таблицы (в `ВЫБРАТЬ` и/или в условиях соединения).

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

```sdbl
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Товар,
    ЕСТЬNULL(ОстаткиТоваров.Остаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(&СегодняшняяДата, Склад = &Склад) КАК ОстаткиТоваров
    ПО ОстаткиТоваров.Номенклатура = СпрНоменклатура.Ссылка
```

В этом варианте передана дата и не использовано измерение `Склад` во внешнем запросе.

#### Правильно

```sdbl
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Товар,
    ЕСТЬNULL(ОстаткиТоваров.Остаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(, Склад = &Склад) КАК ОстаткиТоваров
    ПО ОстаткиТоваров.Номенклатура = СпрНоменклатура.Ссылка
       И ОстаткиТоваров.Склад = &Склад
```

#### См. также

- [#std657: Обращения к виртуальным таблицам](https://v8std.ru/std/657/)
- [#std664: Режим разделения итогов для регистров накопления](https://v8std.ru/std/664/)
- [#std663: Режим разделения итогов для регистров бухгалтерии](https://v8std.ru/std/663/)

#### Проверки
[#bslls:VirtualTableCallWithoutParameters](https://v8std.ru/diagnostics/bslls/VirtualTableCallWithoutParameters/)

#### Источник

https://its.1c.ru/db/v8std#content:733

Эта рекомендация дополняет #std657: Обращения к виртуальным таблицам и описывает практики для виртуальной таблицы Остатки регистров накопления и бухгалтерии.

Обращение к виртуальной таблице без параметров BSLLS:VirtualTableCallWithoutParameters

Обращения к виртуальным таблицам #std657

Режим разделения итогов для регистров бухгалтерии #std663

Режим разделения итогов для регистров накопления #std664

Эффективное обращение к виртуальной таблице «Остатки» #std733


стандарт 737

ID: #std737

# Проверка прав доступа

#### 1.

Если в конфигурации много ролей (от нескольких десятков), не используйте ролевую настройку видимости в элементах форм:

- просмотр/редактирование реквизитов по ролям;
- пользовательскую видимость полей формы по ролям;
- использование команд по ролям.

Рекомендуемые подходы:

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

Учитывайте, что программное управление видимостью может замедлить открытие формы.

Это позволяет:

- упростить работу с элементами, которые могут исчезать из коллекции `Элементы`;
- повысить устойчивость кода к изменению состава ролей;
- упростить контроль использования ролей в конфигурации.

#### Проверки
[#v8cs:form-item-visible-settings-by-roles](https://v8std.ru/diagnostics/v8-code-style/form-item-visible-settings-by-roles/)

#### 2.

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

Вместо этого настраивайте права на:

- разделы командного интерфейса;
- общие формы;
- объекты, включенные в командный интерфейс или рабочую область.

Это повышает предсказуемость интерфейса и упрощает расследование ошибок.

#### 3.

Для проверки прав в коде используйте метод `ПравоДоступа`.

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

```bsl
Если РольДоступна("ДобавлениеИзменениеСтранМира") Тогда ...
Если РольДоступна("ПросмотрОтчетаПопулярныеСтраны") Тогда ...
```

#### Правильно

```bsl
Если ПравоДоступа("Редактирование", Метаданные.Справочники.СтраныМира) Тогда ...
Если ПравоДоступа("Просмотр", Метаданные.Отчеты.ПопулярныеСтраны) Тогда ...
```

Такой подход повышает устойчивость кода к пересмотру состава ролей.

#### Проверки
[#v8cs:using-isinrole](https://v8std.ru/diagnostics/v8-code-style/using-isinrole/)

#### 4.1.

Если роль не дает прав на объекты метаданных и служит только маркером дополнительного права, используйте `РольДоступна`.

При использовании БСП рекомендуется `Пользователи.РолиДоступны`.

Пример без БСП:

```bsl
Если РольДоступна(...) Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда ...
```

Пример с БСП:

```bsl
Если Пользователи.РолиДоступны(...) Тогда ...
```

#### 4.2.

Проектируйте роли с учетом влияния на командный интерфейс.

Если чтение/запись идет в [#std485: привилегированном режиме](https://v8std.ru/std/485/), не задавайте в роли права с RLS-условием `ГДЕ ЛОЖЬ`
В таких случаях проверяйте наличие роли.

Пример: на общую форму `Заметка` права дают роли `ДобавлениеИзменениеЗаметок` и `ЧтениеЗаметок`, а доступ к данным выполняется в привилегированном режиме.
Тогда по `ПравоДоступа` нельзя надежно определить право добавления заметок.

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

Добавлять в роль `ДобавлениеИзменениеЗаметок` фиктивные права на регистр `Заметки` с `ГДЕ ЛОЖЬ` и проверять:

```bsl
Если ПравоДоступа("Редактирование", Метаданные.РегистрыСведений.Заметки) Тогда
```

#### Правильно

```bsl
Если РольДоступна("ДобавлениеИзменениеЗаметок") Или <ЭтоПолноправныйПользователь> Или ПривилегированныйРежим() Тогда
```

Либо с БСП:

```bsl
Если Пользователи.РолиДоступны("ДобавлениеИзменениеЗаметок") Тогда
```

#### См. также

- [#std488: Стандартные роли](https://v8std.ru/std/488/)
- [#std668: Разработка ролей в библиотеках](https://v8std.ru/std/668/)

#### Проверки
[#bslls:IsInRoleMethod](https://v8std.ru/diagnostics/bslls/IsInRoleMethod/)

[#acc:336](https://v8std.ru/diagnostics/acc/336/)
[#acc:341](https://v8std.ru/diagnostics/acc/341/)
[#acc:393](https://v8std.ru/diagnostics/acc/393/)
[#acc:394](https://v8std.ru/diagnostics/acc/394/)
[#acc:395](https://v8std.ru/diagnostics/acc/395/)
[#acc:457](https://v8std.ru/diagnostics/acc/457/)
[#acc:460](https://v8std.ru/diagnostics/acc/460/)
[#acc:461](https://v8std.ru/diagnostics/acc/461/)
[#acc:514](https://v8std.ru/diagnostics/acc/514/)
[#acc:515](https://v8std.ru/diagnostics/acc/515/)
#### Источник

https://its.1c.ru/db/v8std#content:737

Использован метод "РольДоступна()". АПК:336

Использована ролевая настройка видимости для элемента формы. АПК:341

Использована ролевая настройка просмотра для реквизита формы. АПК:393

Использована ролевая настройка редактирования для реквизита формы. АПК:394

Использована ролевая настройка использования для команды формы. АПК:395

Использована ролевая настройка видимости в командном интерфейсе конфигурации. АПК:457

Использована ролевая настройка видимости в рабочей области начальной страницы. АПК:460

Использована ролевая настройка видимости в командном интерфейсе основного раздела. АПК:461

Роль не дает прав ни на один объект метаданных, и к ней нет обращения в коде модулей. АПК:514

Использована функция "Пользователи.РолиДоступны()". АПК:515

Использование метода РольДоступна BSLLS:IsInRoleMethod

Использована ролевая настройка видимости (редактирования, использования) для элемента формы (form-item-visible-settings-by-roles)

Использован метод "РольДоступна" (using-isinrole)

Использование привилегированного режима #std485

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

Разработка ролей в библиотеках #std668

Проверка прав доступа #std737


стандарт 739

ID: #std739

# Размещение сведений о настройках подсистемы

Для настройки функциональности [#std551: библиотеки](https://v8std.ru/std/551/) в конфигурации-потребителе используют [#std553: переопределяемые объекты](https://v8std.ru/std/553/)

Настройки подсистемы обычно делятся на:

- общие для всех объектов подсистемы или для группы объектов;
- специфичные для конкретного объекта.

#### 1.

Общие настройки подсистемы задавайте в переопределяемом модуле.

Для этого создайте процедуру `ПриОпределенииНастроек` с параметром `Настройки` типа `Структура`, который заранее заполнен значениями по умолчанию.

Использование структуры в параметре позволяет расширять программный интерфейс добавлением новых свойств без нарушения [#std644: обратной совместимости](https://v8std.ru/std/644/)

#### Пример

```bsl
Процедура ПриОпределенииНастроек(Настройки) Экспорт

    Настройки.ВыводитьОтчетыВместоВариантов = Истина;
    Настройки.ВыводитьОписания = Истина;
    Настройки.ДругиеОтчеты.ПоказыватьФлажок = Истина;

КонецПроцедуры
```

#### 1.1.

Для определения списка объектов, с которыми работает подсистема, не используйте перебор метаданных с конструкцией [#std499: `Попытка... Исключение`](https://v8std.ru/std/499/)

Вместо этого создавайте отдельную процедуру переопределяемого модуля с явным списком объектов.

Пример: `ПриОпределенииПодключенныхОтчетов`.

#### 1.2.

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

Имена процедур выбирайте по выполняемому действию.
Пример: `ПриРегистрацииИзмененийКлючейВариантовОтчетов`.

Для каждого действия создавайте отдельную процедуру.

#### 2.

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

Для процедуры со сведениями о свойствах, реквизитах или методах используйте имя вида `ПриОпределенииНастроек`.
Пример: `ПриОпределенииНастроекВариантовОтчетов`.

Переопределяемую бизнес-логику для конкретного объекта также размещайте в модуле менеджера.
Наличие конкретных процедур задавайте в `ПриОпределенииНастроек`, чтобы не проверять наличие процедур через [#std499: `Попытка... Исключение`](https://v8std.ru/std/499/)

#### Пример

```bsl
Процедура ПриОпределенииНастроекВариантовОтчетов(Настройки) Экспорт

    Настройки.ОпределитьНастройкиФормы = Истина;
    Настройки.Размещение.Вставить(ВариантыОтчетовКлиентСервер.ИдентификаторНачальнойСтраницы(), "Важный");
    Настройки.ПриПолученииДанныхОтчета = Истина; // Наличие процедуры.

КонецПроцедуры

Процедура ПриПолученииДанныхОтчета(Данные) Экспорт

    Данные.Очистить();
    // Своя процедура получения данных.

КонецПроцедуры
```

Процедура `ПриОпределенииНастроекВариантовОтчетов` задает настройки конкретного отчета и сообщает о наличии процедуры `ПриПолученииДанныхОтчета`, в которой реализована переопределяемая обработка данных.

#### Источник

https://its.1c.ru/db/v8std#content:739

Для настройки функциональности #std551: библиотеки в конфигурации-потребителе используют #std553: переопределяемые объекты.

Перехват исключений в коде #std499

Разработка конфигураций с повторным использованием общего кода и объектов метаданных #std551

Переопределяемые и поставляемые объекты библиотеки #std553

Обеспечение совместимости библиотек #std644

Размещение сведений о настройках подсистемы #std739


стандарт 740

ID: #std740

# Безопасное хранение паролей

#### 1.

При разработке подсистем, которые работают с внешними ресурсами (почта, веб-сервисы, FTP и т. п.), обычно нужно передавать данные аутентификации: логин и пароль.

#### 2.

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

Минимальный уровень защищенности - в файловых базах: файл базы может целиком скопировать любой пользователь ИБ.
В клиент-серверных базах доступ к данным обычно есть только у администраторов СУБД.

Базовый подход: запрашивать логин и пароль у пользователя и сразу использовать их без сохранения в ИБ.

#### Проверки
[#v8cs:unsafe-password-ib-storage](https://v8std.ru/diagnostics/v8-code-style/unsafe-password-ib-storage/)

#### 3.

Иногда это неудобно или невозможно:

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

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

#### 3.1.

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

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

#### 3.2.

Если используется БСП, применяйте безопасное хранилище паролей.
Оно решает ключевые задачи:

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

Для работы с безопасным хранилищем используются процедуры и функции модуля `ОбщегоНазначения`:

- `ЗаписатьДанныеВБезопасноеХранилище()`;
- `ПрочитатьДанныеИзБезопасногоХранилища()`;
- `УдалитьДанныеИзБезопасногоХранилища()`.

Подробнее см. комментарии к этим функциям в БСП и раздел `3.4. Базовая функциональность - Использование при разработке конфигурации - Безопасное хранилище паролей` документации БСП.

#### 3.3.

Не храните пароль в реквизитах формы.
Извлекайте его на сервере непосредственно перед использованием.

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

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

#### Пример

Маскировка пароля в обработчике формы `ПриСозданииНаСервере()`:

```bsl
УстановитьПривилегированныйРежим(Истина);
Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(
    Объект.Ссылка,
    "Пароль, ПарольSMTP"); // Ключи соответствия данных в безопасном хранилище.
УстановитьПривилегированныйРежим(Ложь);

Пароль = ?(ЗначениеЗаполнено(Пароли.Пароль), ЭтотОбъект.УникальныйИдентификатор, "");
ПарольSMTP = ?(ЗначениеЗаполнено(Пароли.ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, "");
```

Запись пароля в обработчике формы `ПриЗаписиНаСервере()`:

```bsl
Если ПарольИзменен Тогда
    УстановитьПривилегированныйРежим(Истина);
    ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
    УстановитьПривилегированныйРежим(Ложь);
    Пароль = ?(ЗначениеЗаполнено(Пароль), ЭтотОбъект.УникальныйИдентификатор, "");
КонецЕсли;

Если ПарольSMTPИзменен Тогда
    УстановитьПривилегированныйРежим(Истина);
    ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ПарольSMTP, "ПарольSMTP");
    УстановитьПривилегированныйРежим(Ложь);
    ПарольSMTP = ?(ЗначениеЗаполнено(ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, "");
КонецЕсли;
```

`Пароль` и `ПарольSMTP` в примере - реквизиты формы.
Если пароль уже сохранен, в реквизит формы записывается уникальный идентификатор, который эмулирует наличие пароля.
После записи объекта пароль сохраняется в безопасном хранилище, а реквизит формы снова затирается уникальным идентификатором.

#### Проверки
[#bslls:UsingHardcodeSecretInformation](https://v8std.ru/diagnostics/bslls/UsingHardcodeSecretInformation/)

[#acc:345](https://v8std.ru/diagnostics/acc/345/)
#### Источник

https://its.1c.ru/db/v8std#content:740

Небезопасное хранение паролей в информационной базе. АПК:345

Хранение конфиденциальной информации в коде BSLLS:UsingHardcodeSecretInformation

Небезопасное хранение паролей в информационной базе (unsafe-password-ib-storage)

Безопасное хранение паролей #std740


стандарт 746

ID: #std746

# Обработчики событий ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления

#### 1.

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

```bsl
Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
    Поля.Добавить("Наименование");
    СтандартнаяОбработка = Ложь;
КонецПроцедуры
```

```bsl
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    Представление = ?(
        ПустаяСтрока(Данные.Наименование),
        НСтр("ru = 'Без описания'"),
        Данные.Наименование);
    СтандартнаяОбработка = Ложь;
КонецПроцедуры
```

#### 2.

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

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

#### 3.

Обработчики могут быть также вызваны, в том числе, при записи и удалении объекта в режиме обмена данными. Представление объекта при этом запрашивается для формирования записи в журнал регистрации. Поэтому к ним предъявляются те же требования, что и к логике регистрации объектов - см. п. 1.2 [#std701: Разработка планов обмена с отборами](https://v8std.ru/std/701/)

Эти требования также справедливы при разработке планов обмена для синхронизации с другими программами (не РИБ, по правилам конвертации) с помощью подсистемы «Обмен данными» Библиотеки стандартных подсистем.
Например, недопустимо [#std697: обращаться к предопределенным элементам](https://v8std.ru/std/697/), которые еще могли быть не загружены в базу или, наоборот, уже удалены в ходе обмена данными:

```bsl
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;

    // Недопустимо: обращение к предопределенному элементу.
    Если Данные.ВидОбразования = Справочники.ВидыОбразованияФизическихЛиц.ПослевузовскоеОбразование Тогда
        Представление = НСтр("ru = 'Послевузовское образование'");
    КонецЕсли;
КонецПроцедуры
```

#### 4.

При реализации обработчиков следует также учитывать требования о поддержке [#std680: толстого клиента, управляемое приложение, клиент-сервер](https://v8std.ru/std/680/)

#### См. также

- [#std449: Получение представлений для ссылочных значений в табличном документе](https://v8std.ru/std/449/)

#### Проверки
[#v8cs:module-accessibility-at-client](https://v8std.ru/diagnostics/v8-code-style/module-accessibility-at-client/)

#### Источник

https://its.1c.ru/db/v8std#content:746

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

Метод или переменная доступны НаКлиенте (module-accessibility-at-client)

Получение представлений для ссылочных значений в табличном документе #std449

Поддержка толстого клиента, управляемое приложение, клиент-сервер #std680

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

Разработка планов обмена с отборами #std701

Обработчики событий ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления #std746


стандарт 748

ID: #std748

# Таймауты при работе с внешними ресурсами

#### 1.

При работе с внешними ресурсами через объекты `WSОпределения`, `WSПрокси`, `HTTPСоединение`, `FTPСоединение`, `ИнтернетПочтовыйПрофиль` обязательно задавайте таймаут, то есть предельное время ожидания операции.

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

Таймаут защищает от внешних проблем:

- нестабильного интернет-соединения;
- влияния антивирусов и неверных настроек брандмауэра;
- неверной настройки прокси-сервера;
- нестабильной работы веб-сервера под нагрузкой или из-за ошибок скриптов.

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

#### 2.

Время операции с внешним ресурсом обычно состоит из шести этапов:

- `DNS Lookup` - определение IP по доменному имени;
- `Connect` - установка соединения с сервером;
- `Send` - отправка данных;
- `Wait` - ожидание обработки на стороне сервера;
- `Receive` - получение ответа;
- `Cache Read` - получение данных от веб-сервера.

Таймаут должен покрывать все этапы.
Если операция не успела завершиться в заданный срок, соединение разрывается.

Выбирайте таймаут по ожидаемой длительности операции:

- для быстрых операций (например, проверка доступности сервера) задавайте небольшой таймаут;
- в общем случае не выбирайте таймаут более 3 минут, чтобы не создавать эффект «зависания» при недоступности удаленной стороны;
- для длительных передач больших объемов данных (этапы `Send`/`Cache Read`) задавайте увеличенный таймаут, но не более 12 часов.

#### 3.

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

#### 3.1.

Для веб-сервисов с операциями дольше ~20 секунд рекомендуется:

- добавить контрольную операцию `Ping`;
- предварительно вызывать `Ping` с малым таймаутом (например, 7 секунд);
- основной прокси получать только после успешного `Ping`.

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

Реализация модуля веб-сервиса `PingPong`:

```bsl
Функция Pong(Знач Параметр)
  Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Привет, %1'"), Параметр);
КонецФункции
```

Вызывающая сторона (без БСП):

```bsl
// Ждем не более минуты
PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60);
Результат = PingPong.Pong(НСтр("ru = 'Мяч'"));
```

#### Правильно

Реализация модуля веб-сервиса `PingPong`:

```bsl
Функция Ping()
  Возврат Истина; // Проверка связи
КонецФункции

Функция Pong(Знач Параметр)
  Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Привет, %1'"), Параметр);
КонецФункции
```

Вызывающая сторона (без БСП):

```bsl
// Ждем не более 3 секунд
PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 3);
PingPong.Ping(); // проверка связи

// Сервис жив, далее работаем с ним и ждем не более минуты
PingPong = Новый WSПрокси(АдресВебСервиса, , , , , 60);
Результат = PingPong.Pong(НСтр("ru = 'Мяч'"));
```

Если используется БСП:

- для веб-сервисов применяйте `ОбщегоНазначения.WSПрокси` (поддерживает контрольный `Ping`);
- для HTTP(S)/FTP(S) применяйте подсистему «Получение файлов через Интернет».

Пример с БСП:

```bsl
// Сделать контрольный вызов Ping и ждать не более минуты на дальнейших операциях.
PingPong = ОбщегоНазначения.WSПрокси(АдресВебСервиса, ..., 60, Истина);
// Сервис точно жив, далее работаем с ним.
Результат = PingPong.Pong(НСтр("ru = 'Мяч'"));
```

#### 3.2.

Для невеб-сервисных ресурсов используйте аналоги `Ping`:

- для REST API - тестовая команда (обычно код 200 означает доступность);
- для FTP/WebDAV - тестовая загрузка (или отправка) файла-пустышки.

#### 3.3.

Если веб-сервис объективно долго работает на этапе `Wait` и ускорить это нельзя, переводите взаимодействие в асинхронный режим:

- запускайте фоновое задание для «тяжелой» операции;
- добавляйте отдельные операции проверки готовности и получения результата.

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

Реализация модуля веб-сервиса `Long`:

```bsl
Функция GetData()
    Результат = <очень длительные вычисления>;
    Возврат Результат;
КонецФункции
```

Вызывающая сторона:

```bsl
Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 10 мин

Результат = Long.GetData();
```

#### Правильно

Реализация модуля веб-сервиса `Long`:

```bsl
Функция StartDoLong()
    // запуск фонового задания
    ИдентификаторОперации = ...
    // возвращаем идентификатор операции для отслеживания ее готовности
    Возврат ИдентификаторОперации;
КонецФункции

Функция IsReady(Знач ИдентификаторОперации)
    // проверяем, завершено ли фоновое задание
    Готовность = ...
    Возврат Готовность;
КонецФункции

Функция GetData(Знач ИдентификаторОперации)
    Результат = <получаем уже готовый результат по переданному идентификатору>;
    Возврат Результат;
КонецФункции
```

Вызывающая сторона:

```bsl
Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 10 мин

ИдентификаторОперации = Long.StartDoLong();

Пока Не Long.IsReady(ИдентификаторОперации) Цикл
    <ждем определенный интервал времени>
КонецЦикла;

Результат = Long.GetData(ИдентификаторОперации);
```

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

#### 4.

Рекомендуемые значения таймаутов:

| Операция | Таймаут (секунд) |
| --- | --- |
| Получение описания веб-сервиса | 7 |
| Проверка корректности адреса, работа с менеджером сервиса в модели сервиса, другие быстрые операции | 10-20 |
| Получение сведений по одному контрагенту, обмен сообщениями, отправка SMS, удаленное администрирование ИБ в модели сервиса | 60-120 (1) |
| Передача сообщений обмена через веб-сервис или получение файла до 1 Мб | 120-180 (1) |
| Загрузка файлов более 1 Мб | Если известен размер файла: `размер_в_Мб * 128` (2); иначе предельное время загрузки, но не более `43200` (3) |

(1) Вызывать после контрольной операции `Ping`.

(2) 1 Мб при скорости 64 кбит/с загружается примерно 128 секунд; в ряде сценариев сотовые операторы ограничивают скорость до этого уровня.

(3) 43200 секунд (12 часов) - компромисс: в нештатной ситуации процесс «отвиснет» и вернет управление, а не зависнет бесконечно.

#### Проверки
[#bslls:TimeoutsInExternalResources](https://v8std.ru/diagnostics/bslls/TimeoutsInExternalResources/)

[#acc:397](https://v8std.ru/diagnostics/acc/397/)
[#acc:398](https://v8std.ru/diagnostics/acc/398/)
#### Источник

https://its.1c.ru/db/v8std#content:748

При работе с внешними ресурсами через объекты WSОпределения, WSПрокси, HTTPСоединение, FTPСоединение, ИнтернетПочтовыйПрофиль обязательно задавайте таймаут, то есть предельное...

Не задан таймаут для объекта при работе с внешними ресурсами. АПК:397

Задан нулевой таймаут для объекта при работе с внешними ресурсами. АПК:398

Таймауты при работе с внешними ресурсами BSLLS:TimeoutsInExternalResources

Таймауты при работе с внешними ресурсами #std748


стандарт 752

ID: #std752

# Обработчик события ПередУдалением

#### 1.

В обработчике `ПередУдалением` модуля объекта выполняйте действия, которые должны быть сделаны до удаления объекта.

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

#### В стандарте не указано

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

#### 2.

Все действия в обработчике `ПередУдалением` выполняйте только после проверки `ОбменДанными.Загрузка`.

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

#### Пример

```bsl
Процедура ПередУдалением(Отказ)

    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Действия перед удалением объекта.
    ОчиститьСсылкиНаУдаляемыйФайл();

КонецПроцедуры
```

#### См. также

- [#std465: Обработчик события ПриЗаписи](https://v8std.ru/std/465/)
- [#std773: Использование признака ОбменДанными.Загрузка в обработчиках событий объекта](https://v8std.ru/std/773/)

#### Проверки
[#bslls:DataExchangeLoading](https://v8std.ru/diagnostics/bslls/DataExchangeLoading/)
[#v8cs:data-exchange-load](https://v8std.ru/diagnostics/v8-code-style/data-exchange-load/)

[#acc:75](https://v8std.ru/diagnostics/acc/75/)
#### Источник

https://its.1c.ru/db/v8std#content:752

В обработчике ПередУдалением модуля объекта выполняйте действия, которые должны быть сделаны до удаления объекта.

Отсутствует обязательная конструкция "Если ОбменДанными.Загрузка Тогда ...". АПК:75

Отсутствует проверка признака ОбменДанными.Загрузка в обработчике событий объекта BSLLS:DataExchangeLoading

Проверка ОбменДанными.Загрузка в обработчике события (data-exchange-load)

Обработчик события ПриЗаписи #std465

Использование признака ОбменДанными.Загрузка в обработчиках событий объекта #std773

Обработчик события ПередУдалением #std752


стандарт 758

ID: #std758

# Псевдонимы источников данных в запросах

#### 1.

Псевдоним источника данных должен быть осмысленным и отражать назначение источника в текущем контексте.

Требования к псевдонимам близки к требованиям к [#std454: именам переменных в коде](https://v8std.ru/std/454/)

- образуйте псевдонимы от терминов предметной области;
- пишите слитно, с заглавной буквы в каждом слове (например, `ТоварыНаСкладах`);
- не начинайте псевдоним с подчеркивания;
- не используйте псевдоним из одного символа.

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

```sdbl
ВЫБРАТЬ
    Таблица1.Ссылка КАК Товар,
    ЕстьNULL(Таблица2.КоличествоОстаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК Таблица1
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Таблица2
        ПО Таблица1.Ссылка = Таблица2.Номенклатура
```

#### Правильно

```sdbl
ВЫБРАТЬ
    ВсяНоменклатура.Ссылка КАК Товар,
    ЕстьNULL(ОстаткиНаСкладах.КоличествоОстаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК ВсяНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ОстаткиНаСкладах
        ПО ВсяНоменклатура.Ссылка = ОстаткиНаСкладах.Номенклатура
```

Не рекомендуется использовать в качестве псевдонимов имена классов метаданных (`Справочник`, `Документ` и т.д.), так как они обычно не описывают роль источника в конкретном запросе.

#### 2.

Для универсальных механизмов, работающих с произвольными таблицами, допустимы универсальные псевдонимы.

#### Пример

```bsl
"ВЫБРАТЬ
    |   Таблица.Наименование КАК Наименование,
    |   Таблица.Код КАК Код
    |ИЗ
    |   &Таблица КАК Таблица";

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Таблица", "Справочник." + ИмяСправочника);
```

#### Источник

https://its.1c.ru/db/v8std#content:758

Правила образования имен переменных #std454

Псевдонимы источников данных в запросах #std758


стандарт 759

ID: #std759

# Несущественные предупреждения проверки конфигурации

#### 1.

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

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

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

#### 2.

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

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

Сценарии разбора таких предупреждений описаны в.

#### См. также

- [#std467: Общие требования к конфигурации](https://v8std.ru/std/467/)

#### Проверки
[#acc:561](https://v8std.ru/diagnostics/acc/561/)
[#acc:562](https://v8std.ru/diagnostics/acc/562/)
[#acc:563](https://v8std.ru/diagnostics/acc/563/)
[#acc:564](https://v8std.ru/diagnostics/acc/564/)
[#acc:565](https://v8std.ru/diagnostics/acc/565/)
[#acc:566](https://v8std.ru/diagnostics/acc/566/)
[#acc:567](https://v8std.ru/diagnostics/acc/567/)
[#acc:568](https://v8std.ru/diagnostics/acc/568/)
[#acc:569](https://v8std.ru/diagnostics/acc/569/)
[#acc:570](https://v8std.ru/diagnostics/acc/570/)
[#acc:571](https://v8std.ru/diagnostics/acc/571/)
[#acc:572](https://v8std.ru/diagnostics/acc/572/)
[#acc:573](https://v8std.ru/diagnostics/acc/573/)
[#acc:574](https://v8std.ru/diagnostics/acc/574/)

#### Источник

https://its.1c.ru/db/v8std#content:759

Ошибка платформенной проверки конфигурации. АПК:561

Ошибка платформенной проверки конфигурации: Возможно ошибочное свойство. АПК:562

Ошибка платформенной проверки конфигурации: Возможно ошибочный метод. АПК:563

Ошибка платформенной проверки конфигурации: Возможно ошибочный параметр. АПК:564

Ошибка платформенной проверки конфигурации: Использование модального вызова. АПК:565

Ошибка платформенной проверки конфигурации: Использование синхронного вызова. АПК:566

Ошибка платформенной проверки конфигурации: Не обнаружено ссылок на процедуру. АПК:567

Ошибка платформенной проверки конфигурации: Не обнаружено ссылок на функцию. АПК:568

Ошибка платформенной проверки конфигурации: Неразрешимые ссылки на объекты метаданных. АПК:569

Ошибка платформенной проверки конфигурации: Отсутствует обработчик. АПК:570

Ошибка платформенной проверки конфигурации: Переменная не определена. АПК:571

Ошибка платформенной проверки конфигурации: Процедура или функция с указанным именем не определена. АПК:572

Ошибка платформенной проверки конфигурации: Пустой обработчик. АПК:573

Ошибка платформенной проверки конфигурации: (Проверка: Мобильный клиент). АПК:574

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

Несущественные предупреждения проверки конфигурации #std759


стандарт 760

ID: #std760

# Ограничения на регламентные задания при работе в модели сервиса

#### 1.

В прикладных решениях, ориентированных на работу в модели сервиса по [Технологии 1cFresh](https://v8.1c.ru/platforma/tekhnologiya-1cfresh/), не должно быть регламентных заданий, включенных в состав любого из разделителей.

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

#### 2.

Если нужно регулярно выполнять программный код в приложениях пользователя в разделенной ИБ, используйте подсистему БТС `Очередь заданий` или аналогичный механизм очереди.

#### 2.1.

Пример № 1.

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

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

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

Включить добавленное задание в состав общих реквизитов, разделяющих данные.

#### Правильно

- Исключить добавленное задание из состава общих реквизитов, разделяющих данные.
- В общем модуле `ОчередьЗаданийПереопределяемый` в процедуру `ПриПолученииСпискаШаблонов` добавить:

```bsl
Шаблоны.Добавить(Метаданные.РегламентныеЗадания.ПересчетИтогов.ИмяМетода);
```

#### 2.2.

Пример № 2.

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

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

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

#### Правильно

- Добавить в конфигурацию непредопределенное регламентное задание `ОбменССайтом`.
- Исключить это задание из состава общих реквизитов, разделяющих данные.
- В общем модуле `ОчередьЗаданийПереопределяемый` в процедуру `ПриОпределенииПсевдонимовОбработчиков` добавить:

```bsl
СоответствиеИменПсевдонимам.Вставить(Метаданные.РегламентныеЗадания.ОбменССайтом.ИмяМетода);
```

- При включении функциональной опции `Обмен с сайтом` добавить задание или включить его использование через:
  - `РегламентныеЗаданияСервер.ДобавитьЗадание` - если задания еще нет;
  - `РегламентныеЗаданияСервер.ИзменитьЗадание` - если задание есть, но использование выключено.
- При выключении функциональной опции удалить задание или отключить его использование через:
  - `РегламентныеЗаданияСервер.УдалитьЗадание` - если задание существует;
  - `РегламентныеЗаданияСервер.ИзменитьЗадание` - если задание существует и использование включено.

#### 2.3.

Пример № 3.

Задание из примера № 2 нужно выполнять от имени определенного пользователя.

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

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

#### Правильно

- Добавить в конфигурацию регламентное задание, исключенное из состава общих реквизитов, разделяющих данные.
- Создать задание через `РегламентныеЗаданияСервер.ДобавитьЗадание`, передав в параметрах имя пользователя.

#### 3.

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

Для управления заданиями используйте программный интерфейс БСП из модуля `РегламентныеЗаданияСервер`.

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

```bsl
// Ищем задание по наименованию.
Отбор = Новый Структура();
Отбор.Вставить("Метаданные", "ПроверкаЦен");
Задания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);

// Проверяем, что задание найдено.
Если Задания.Количество() <> 1 Тогда
    // Запись в журнал ошибки опущена.
    Возврат;
КонецЕсли;

// Включаем найденное задание.
НашеЗадание = Задания[0];
НашеЗадание.Использование = Истина;
НашеЗадание.Записать();
```

#### Правильно

```bsl
// Ищем задание по наименованию.
Отбор = Новый Структура();
Отбор.Вставить("Метаданные", "ПроверкаЦен");
Задания = РегламентныеЗаданияСервер.НайтиЗадания(Отбор);

// Проверяем, что задание найдено.
Если Задания.Количество() <> 1 Тогда
    // Запись в журнал ошибки опущена.
    Возврат;
КонецЕсли;

// Включаем найденное задание.
НашеЗадание = Задания[0];
Параметры = Новый Структура();
Параметры.Вставить("Использование", Истина);
РегламентныеЗаданияСервер.ИзменитьЗадание(НашеЗадание.УникальныйИдентификатор, Параметры);
```

#### 4.

Подсистема `Очередь заданий` не гарантирует выполнение задания строго по расписанию.

Точность зависит от:

- общего количества запланированных заданий;
- длительности их выполнения;
- количества исполняющих потоков (регулируется константой `Максимальное количество исполняющихся фоновых заданий`).

#### 4.1.

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

#### 4.2.

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

- Если можно настроить push-уведомления от внешней системы, не используйте регламентное задание:
  - загружайте данные только при получении уведомления;
  - отправляйте данные только при реальной потребности.
  Пример push-доставки есть в Системе взаимодействий при приеме входящего SIP-звонка.
- В остальных случаях оставьте регламентное задание (через очередь заданий), но оперативное получение и отправку данных выполняйте тогда, когда пользователь фактически работает в нужном рабочем месте.

Пример: отправка и получение почты должны выполняться раз в 5 минут, но в нагруженной сервисной базе задание запускается раз в 1 ч. 40 мин, что неприемлемо.

В таком случае организуйте оперативную работу с почтой так:

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

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

#### Для информации

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

#### Проверки

[#acc:453](https://v8std.ru/diagnostics/acc/453/)
[#acc:454](https://v8std.ru/diagnostics/acc/454/)
[#acc:455](https://v8std.ru/diagnostics/acc/455/)
#### Источник

https://its.1c.ru/db/v8std#content:760

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

Обращение к менеджеру регламентных заданий при наличии подсистемы "Технология сервиса". АПК:453

Регламентное задание включено в состав разделителя. АПК:454

Регламентное задание с включенным использованием отсутствует в процедуре "ОчередьЗаданийПереопределяемый.ПриПолученииСпискаШаблонов". АПК:455

Ограничения на регламентные задания при работе в модели сервиса #std760


стандарт 761

ID: #std761

# Интерфейсные тексты в коде: требования по локализации

#### 1.

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

Для этого используйте `НСтр` вместо прямых строковых литералов.

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

```bsl
ПоказатьПредупреждение(, "Для выполнения операции необходимо установить расширение работы с файлами.");
```

#### Правильно

```bsl
ПоказатьПредупреждение(, НСтр("ru='Для выполнения операции необходимо установить расширение работы с файлами.'"));
```

Также важно корректно использовать `НСтр`.

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

```bsl
ТекстСообщения = "ru='Для выполнения операции необходимо установить расширение работы с файлами.'";
ПоказатьПредупреждение(, НСтр(ТекстСообщения));
```

#### Правильно

```bsl
ТекстСообщения = НСтр("ru='Для выполнения операции необходимо установить расширение работы с файлами.'");
ПоказатьПредупреждение(, ТекстСообщения);
```

#### 2.

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

Это нужно из-за разного порядка слов, знаков препинания и грамматики в разных языках.

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

```bsl
СообщениеОНехватке = "Не хватает товара " + НаименованиеТовара + " на складе " + НаименованиеСклада + ".";
```

#### Правильно

```bsl
ТекстСообщения = НСтр("ru = 'Не хватает товара %1 на складе %2.'");
СообщениеОНехватке = СтрШаблон(ТекстСообщения, НаименованиеТовара, НаименованиеСклада);
```

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

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

```bsl
НСтр("ru = '%1 пользователя ""%2"" в группу ""%3""?'")
```

#### Правильно

```bsl
НСтр("ru = 'Включить пользователя ""%2"" в группу ""%3""?'");
НСтр("ru = 'Копировать пользователя ""%2"" в группу ""%3""?'");
НСтр("ru = 'Удалить пользователя ""%2"" из группы ""%3""?'");
```

Допустимо:

- формировать сообщение из нескольких предложений, если каждое предложение отдельно локализуется через `НСтр`;
- использовать предложения с двоеточием (например, `НСтр("ru = 'Создание каталога не выполнено по причине:'")`).

Именованные параметры подстановки используйте только в вариантах `[Параметр]` и `%Параметр%`.
Имя параметра должно соответствовать [#std454: Правилам образования имен переменных](https://v8std.ru/std/454/)

#### Правильно

```bsl
СообщениеОНехватке = НСтр("ru='Не хватает товара %Товар% на складе %Склад%.'");
СообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, "%Товар%", НаименованиеТовара);
СообщениеОНехватке = СтрЗаменить(СообщениеОНехватке, "%Склад%", НаименованиеСклада);
```

#### 3.

Если в конфигурации используется БСП, для составных форматированных строк вместо объекта `ФорматированнаяСтрока` применяйте функцию `ФорматированнаяСтрока` модулей `СтроковыеФункции` или `СтроковыеФункцииКлиент`.

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

```bsl
Текст = Новый Массив;
Текст.Добавить(НСтр("ru = 'Перед удалением расширения рекомендуется'"));
Текст.Добавить(" ");
Текст.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'выполнить резервное копирование информационной базы.'"), ШрифтыСтиля.ПолужирныйШрифт));
ТекстПредупреждения = Новый ФорматированнаяСтрока(Текст);
```

#### Правильно

```bsl
ТекстПредупреждения = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
    НСтр("ru = 'Перед удалением расширения рекомендуется <b>выполнить резервное копирование информационной базы</b>.'"));
```

#### 4.

В `НСтр` строку ограничивайте одинарными кавычками.

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

```bsl
ПоказатьПредупреждение(, НСтр("ru=Переменная типа ""Строка"""));
ПоказатьПредупреждение(, НСтр("ru=""Переменная типа ""Строка"""""));
```

#### Правильно

```bsl
ПоказатьПредупреждение(, НСтр("ru='Переменная типа ""Строка""'"));
```

#### 5.

Не выводите пользователю имена объектов метаданных и внутренние идентификаторы из кода.

Выводите синонимы (представления), и по возможности получайте их напрямую из метаданных через `Представление`.

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

```bsl
СообщениеОшибка = НСтр("ru='Обнаружены отрицательные остатки по регистру ТоварыОрганизаций.'");
```

#### Правильно

```bsl
СообщениеОшибка = СтрШаблон(
    НСтр("ru = 'Обнаружены отрицательные остатки по регистру ""%1"".'"),
    Метаданные.РегистрыНакопления.ТоварыОрганизаций.Представление());
```

Сокращенный вариант тоже допустим:

```bsl
СообщениеОшибка = СтрШаблон(
    НСтр("ru = 'Обнаружены отрицательные остатки по регистру ""%1"".'"),
    Метаданные.РегистрыНакопления.ТоварыОрганизаций);
```

#### 5.1.

Исключение: сообщения для разработчиков и интерфейсы инструментов разработчика/внедренца.

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

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

```bsl
СообщениеОшибка = НСтр("ru = 'Ошибка в функции ЕстьРоль модуля УправлениеДоступом.'");
```

#### Правильно

```bsl
ИмяФункции = "УправлениеДоступом.ЕстьРоль";
СообщениеОшибка = СтрШаблон(НСтр("ru = 'Ошибка в функции %1.'"), ИмяФункции);
```

#### Правильно

```bsl
ИмяФункции = "Документы.АвансовыйОтчет.АдаптированныйТекстЗапросаДвиженийПоРегистру";
СообщениеОшибка = СтрШаблон(
    НСтр("ru = 'Для исправления движений документа необходимо вызвать функцию %1.'"),
    ИмяФункции);
```

Для имен объектов метаданных предпочтительно использовать `ПолноеИмя`.

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

```bsl
СообщениеОшибка = НСтр("ru='Подсистема некорректно встроена в регистр ТоварыОрганизаций.'");
```

#### Правильно

```bsl
СообщениеОшибка = СтрШаблон(
    НСтр("ru = 'Подсистема некорректно встроена в регистр %1.'"),
    Метаданные.РегистрыНакопления.ТоварыОрганизаций.ПолноеИмя());
```

#### 6.

При использовании функций `ЧислоПрописью`, `ПредставлениеПериода`, `СтрокаСЧислом` не указывайте параметр `Л=` (`L=`) в строке форматирования.

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

```bsl
СуммаПрописью = ЧислоПрописью(2341.56, "Л = ru_RU; ДП = Истина", НСтр("ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'"));
```

#### Правильно

```bsl
СуммаПрописью = ЧислоПрописью(2341.56, "ДП = Истина", НСтр("ru='доллар,доллара,долларов,м,цент,цента,центов,м,2'"));
```

#### 7.

Не вызывайте функцию `ПолучитьСклоненияСтрокиПоЧислу`, так как она предназначена только для русскоязычного интерфейса.

Используйте:

- `СтроковыеФункцииКлиентСервер.СтрокаСЧисломДляЛюбогоЯзыка`;
- `РаботаСКурсамиВалют.СформироватьСуммуПрописью`;
- `СтрокаСЧислом`;
- `ЧислоПрописью`.

Либо реализуйте собственные прикладные функции.

#### 8.

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

Но неязыковые символы (обычно перевод строки) в начале/конце текста выделяйте в отдельные строковые литералы.

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

```bsl
ТекстСообщения = НСтр("ru = 'Не удалось сохранить файл документа по причине:
  |'")
  + ИнформацияОбОшибке;
```

#### Правильно

```bsl
ТекстСообщения = НСтр("ru = 'Не удалось сохранить файл документа по причине:'")
  + Символы.ПС + ИнформацияОбОшибке;
```

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

#### 9.

При вызове `ПоказатьВопрос` с указанием кнопок в параметре `Кнопки`:

- по возможности используйте системное перечисление `КодВозвратаДиалога`;
- если в перечислении нет нужной кнопки, задавайте ее представление через `НСтр`.

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

```bsl
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Отключить");
Кнопки.Добавить("Нет");
ПоказатьВопрос(..., Кнопки);
```

#### Правильно

```bsl
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Отключить", НСтр("ru='Отключить'"));
Кнопки.Добавить(КодВозвратаДиалога.Нет);
ПоказатьВопрос(..., Кнопки);
```

#### См. также

- [#std498: Использование Журнала регистрации](https://v8std.ru/std/498/)

#### Проверки

[#acc:492](https://v8std.ru/diagnostics/acc/492/)
[#acc:1297](https://v8std.ru/diagnostics/acc/1297/)
[#acc:1298](https://v8std.ru/diagnostics/acc/1298/)
[#acc:1299](https://v8std.ru/diagnostics/acc/1299/)
[#acc:1354](https://v8std.ru/diagnostics/acc/1354/)
[#acc:1355](https://v8std.ru/diagnostics/acc/1355/)
[#acc:1356](https://v8std.ru/diagnostics/acc/1356/)
[#acc:1357](https://v8std.ru/diagnostics/acc/1357/)
[#acc:1358](https://v8std.ru/diagnostics/acc/1358/)
[#acc:1359](https://v8std.ru/diagnostics/acc/1359/)
#### Источник

https://its.1c.ru/db/v8std#content:761

Строка не локализована. Возможно, она видна пользователю. АПК:1297

Нарушен синтаксис описания локализованной строки. Должен быть "НСтр("ru='...'")" или "NStr("en='...'")". АПК:1298

Локализуемая строка начинается или заканчивается непечатаемым символом (например: пробел, таб, перенос). АПК:1299

Локализуемая строка состоит из нелокализуемых символов. АПК:1354

Конкатенация локализуемых строк. АПК:1355

В качестве параметра конструктора "Новый ФорматированнаяСтрока" использована составная форматированная строка. АПК:1356

В качестве параметра метода "ЧислоПрописью" используется форматированная строка с параметром "Л="("L=") . АПК:1357

В качестве параметра метода "ПредставлениеПериода" используется форматированная строка с параметром "Л="("L=") . АПК:1358

В качестве параметра метода "СтрокаСЧислом" используется форматированная строка с параметром "Л="("L=") . АПК:1359

Неверно задан именованный параметр подстановки. АПК:492

Правила образования имен переменных #std454

Использование Журнала регистрации #std498

Интерфейсные тексты в коде: требования по локализации #std761


стандарт 762

ID: #std762

# Запросы, динамические списки и отчеты на СКД: требования по локализации

#### 1.

Если строковые литералы из текста запроса выводятся пользователю, не оставляйте их в тексте `#!`.

Передавайте такие значения через параметры запроса и задавайте через `НСтр`.

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

```sdbl
ВЫБРАТЬ
    Версии.Ссылка,
    ВЫБОР
        КОГДА Версии.Выпущена = ИСТИНА ТОГДА "выпущена"
        ИНАЧЕ "в разработке"
    КОНЕЦ КАК ТекстПояснения
ИЗ
    Справочник.Версии КАК Версии
```

#### Также неправильно

```bsl
ТекстЗапроса =
    "ВЫБРАТЬ
    |   ВЫБОР
    |       КОГДА Версии.Выпущена = ИСТИНА ТОГДА &ТекстВыпущеннойВерсии
    |       ИНАЧЕ &ТекстНеВыпущеннойВерсии
    |   КОНЕЦ";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТекстВыпущеннойВерсии", НСтр("ru='выпущена'"));
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТекстНеВыпущеннойВерсии", НСтр("ru='в разработке'"));
```

#### Правильно

```bsl
ЗапросПоВерсиям = Новый Запрос(
    "ВЫБРАТЬ
    |   Версии.Ссылка,
    |   ВЫБОР
    |       КОГДА Версии.Выпущена = ИСТИНА ТОГДА &ТекстВыпущеннойВерсии
    |       ИНАЧЕ &ТекстНеВыпущеннойВерсии
    |   КОНЕЦ КАК ТекстПояснения
    |ИЗ
    |   Справочник.Версии КАК Версии");

ЗапросПоВерсиям.УстановитьПараметр("ТекстВыпущеннойВерсии", НСтр("ru='выпущена'"));
ЗапросПоВерсиям.УстановитьПараметр("ТекстНеВыпущеннойВерсии", НСтр("ru='в разработке'"));
```

#### 2.

Те же требования применяйте к выражениям СКД и запросам наборов данных СКД, если они формируют интерфейсный текст.

- Для параметров СКД с текстовыми значениями используйте технические ключи по правилам [#std454: Правила образования имен переменных](https://v8std.ru/std/454/), а человекочитаемый текст задавайте локализуемо

  Изображение: Пример локализации параметров СКД (762.img1.png)

- Если значение параметра зависит от прикладной логики, задавайте его в модуле отчета в `ПриКомпоновкеРезультата`, а не в колонке `Выражение`.

- В выражениях настройки СКД (`Выражение представления`, `Выражение упорядочивания` и др.) используйте `НСтр`, аналогично модульному коду.

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

```sdbl
ВЫБОР
    КОГДА ВидОперации = "Отгрузка клиентам" ТОГДА 1
    КОГДА ВидОперации = "Возвраты товаров от клиентов" ТОГДА 2
    КОГДА ВидОперации = "Приемка от поставщиков" ТОГДА 3
КОНЕЦ
```

#### Правильно

```sdbl
ВЫБОР
    КОГДА ВидОперации = &ВидОперацииОтгрузкаКлиентам ТОГДА 1
    КОГДА ВидОперации = &ВидОперацииВозвратыТоваровОтКлиентов ТОГДА 2
    КОГДА ВидОперации = &ВидОперацииПриемкаОтПоставщиков ТОГДА 3
КОНЕЦ
```

#### Правильно

```sdbl
Выбор Когда Объект = Раздел
    Тогда Выбор
        Когда Раздел = Значение(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
            Тогда НСтр("ru='<Для всех разделов и объектов, кроме указанных>'")
        Иначе НСтр("ru='<Для всех объектов, кроме указанных>'")
    Конец
    Иначе Объект
Конец
```

#### 3.

Для поля выборки отчета СКД, полученного вычислением с псевдонимом, задавайте синоним явно.

Не используйте автоматически сгенерированный заголовок по имени или псевдониму.

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

Изображение: Автосгенерированный заголовок (762.img2.png)

#### Правильно

Изображение: Явно заданный синоним (762.img3.png)

Если не установить синоним, такие поля хуже обнаруживаются при поиске интерфейсных текстов.

#### 4.

В заголовках отчетов СКД, полей, вычисляемых полей и параметров допускаются параметры подстановки `СтрШаблон`:

- `%1`, `%2` и т.д.;
- `[Параметр]`;
- `%Параметр%`.

Имя параметра должно соответствовать правилам [#std454: Правила образования имен переменных](https://v8std.ru/std/454/)

| Заменяйте параметры в `ПриКомпоновкеРезультата`, когда заголовки зависят от прикладной логики. |
| --- |
| Изображение: Параметры в макете СКД (762.img4.png) |
| Изображение: Параметры в вычисляемых полях (762.img5.png) |
| Изображение: Параметры в представлении (762.img6.png) |
| Изображение: Параметры в упорядочивании (762.img7.png) |
| Изображение: Результат подстановки (762.img8.png) |

#### См. также

- [#std437: Оформление текстов запросов](https://v8std.ru/std/437/)

#### Проверки

[#acc:320](https://v8std.ru/diagnostics/acc/320/)
[#acc:462](https://v8std.ru/diagnostics/acc/462/)
[#acc:463](https://v8std.ru/diagnostics/acc/463/)
[#acc:465](https://v8std.ru/diagnostics/acc/465/)
[#acc:491](https://v8std.ru/diagnostics/acc/491/)
[#acc:1297](https://v8std.ru/diagnostics/acc/1297/)
[#acc:1298](https://v8std.ru/diagnostics/acc/1298/)
[#acc:1299](https://v8std.ru/diagnostics/acc/1299/)
[#acc:1300](https://v8std.ru/diagnostics/acc/1300/)
[#acc:1354](https://v8std.ru/diagnostics/acc/1354/)
#### Источник

https://its.1c.ru/db/v8std#content:762

Если строковые литералы из текста запроса выводятся пользователю, не оставляйте их в тексте #!sdbl.

В тексте запроса находится строковый литерал. АПК:1300

НСтр() в выражении параметра макета. Значение параметра нужно задавать с помощью НСтр() не в колонке "Выражение", а в модуле отчета. АПК:320

Для строковой константы запроса СКД не установлено представление доступного значения. АПК:462

Строковая константа в запросе СКД не соответствует правилам образования имен переменных. АПК:463

Не заполнен заголовок поля выборки в запросе СКД. АПК:465

Некорректная локализация фрагмента текста запроса. АПК:491

Оформление текстов запросов #std437

Запросы, динамические списки и отчеты на СКД: требования по локализации #std762


стандарт 763

ID: #std763

# Форматирование даты, числа, Булево: требования по локализации

#### 1.

При использовании функции `Формат` в ряде случаев применяйте `НСтр` для форматной строки.

Форматная строка, заданная в свойствах метаданных (форм), всегда подлежит локализации, как и синоним.

#### 1.1.

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

Поэтому вместо явного формата даты используйте локальный формат даты `ДЛФ`.

Если нужен произвольный формат (`ДФ`) или представление пустой даты (`ДП`), оборачивайте форматную строку в `НСтр`, чтобы она могла переводиться.

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

```bsl
Формат(ДатаУтверждения, "ДФ=дд.ММ.гггг");
Формат(ДатаУтверждения, "ДФ=ММММ гггг") + " г.";
```

#### Правильно

```bsl
Формат(ДатаУтверждения, "ДЛФ=ДД");
Формат(ДатаУтверждения, НСтр("ru='ДФ=''ММММ гггг ""г.""'''"));
```

#### 1.2.

Для чисел применяйте `НСтр` к форматной строке, когда:

- задается нечисловое представление нулевого значения (`ЧН`);
- задан шаблон форматирования числа (`ЧФ`);
- переопределяется разделитель дробной части (`ЧРД`).

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

```bsl
Предупреждение(Формат(100, "ЧН=Отсутствует"));
Предупреждение(Формат(100, "ЧФ=""$Ч' / Час'"""));
```

#### Правильно

```bsl
Предупреждение(Формат(100, НСтр("ru = 'ЧН=Отсутствует'")));
Предупреждение(Формат(100, НСтр("ru = 'ЧФ=""$Ч'' / Час''""'"))); // "$100 / Час"
```

#### 1.3.

Для вывода пользователю значений `Булево` всегда применяйте `НСтр` к форматной строке.

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

```bsl
Предупреждение(Формат(Истина, "БЛ=Нет; БИ=Да"));
```

#### Правильно

```bsl
Предупреждение(Формат(Истина, НСтр("ru='БЛ=Нет; БИ=Да'")));
```

#### 1.4.

Не переопределяйте локализацию отображения данных по умолчанию (формат ОС).

При использовании `Формат` избегайте параметра `L=`.

#### 2.

При задании формата в полях ввода форм и полях отчетов на СКД также предпочитайте локальный формат даты.

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

#### 3.

При переопределении стандартных представлений полей в отчетах на СКД соблюдайте те же правила, что и в модульном коде.

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

```bsl
"N " + ВОтветНаНомер + " от " + Формат(ВОтветНаДата, "ДФ=dd.MM.yyyy")
```

#### Правильно

```bsl
СтрШаблон(
  НСтр("ru = 'N%1 от %2'"),
  ВОтветНаНомер,
  Формат(ВОтветНаДата, "ДЛФ=D"))
```

#### 4.

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

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

В общем случае для сериализации используйте `XMLСтрока`, для десериализации `XMLЗначение` или `ПривестиЗначение` объекта `ОписаниеТипов`.

#### 4.1.

Для собственных форматов обмена рекомендуется сериализация дат в формате ISO `ГГГГ-ММ-ДДTЧЧ:ММ:ССZ` (тип `dateTime` XML Schema): http://www.w3.org/TR/xmlschema-2/#dateTime.

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

```bsl
Строка = Формат(Дата, "ДФ=гггг-ММ-ддTЧЧ:мм:сс"); // Сериализация
```

#### Правильно

```bsl
// Сериализация
Строка = XMLСтрока(Дата);
// Или
Строка = ЗаписатьДатуJSON(Дата, ФорматДатыJSON.ISO);

// Десериализация
ОписаниеТипа = Новый ОписаниеТипов("Дата");
Дата = ОписаниеТипа.ПривестиЗначение(Строка);

// Или
Дата = XMLЗначение(Тип("Дата"), Строка);
// Или
Дата = ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO);
```

#### 4.2.

Для чисел:

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

```bsl
// Сериализация
Строка = Строка(Число);
// Или
Строка = Формат(Число);
```

#### Правильно

```bsl
Строка = XMLСтрока(Число); // Сериализация
Число = XMLЗначение(Тип("Число"), Строка); // Десериализация
```

#### 4.3.

Для `Булево`:

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

```bsl
// Сериализация
Строка = Строка(Булево);
// Или
Строка = Формат(Булево);
// Или
Строка = Формат(Булево, "БЛ=off; БИ=on");
```

#### Правильно

```bsl
// Сериализация
Строка = XMLСтрока(Булево);

// Десериализация
Булево = XMLЗначение(Тип("Булево"), Строка);

// Либо явное преобразование в прикладной формат
Строка = ?(Булево, "on", "off");
```

#### Проверки

[#acc:335](https://v8std.ru/diagnostics/acc/335/)
[#acc:1367](https://v8std.ru/diagnostics/acc/1367/)
[#acc:1368](https://v8std.ru/diagnostics/acc/1368/)
[#acc:1369](https://v8std.ru/diagnostics/acc/1369/)
#### Источник

https://its.1c.ru/db/v8std#content:763

При использовании функции Формат в ряде случаев применяйте НСтр для форматной строки.

Отсутствует локализация при форматировании даты. АПК:1367

Отсутствует локализация при форматировании числа. АПК:1368

Отсутствует локализация при форматировании Булево. АПК:1369

Обнаружена нелокализованная дата. АПК:335

Форматирование даты, числа, Булево: требования по локализации #std763


стандарт 764

ID: #std764

# Строковые константные выражения в коде: требования по локализации

#### 1.

Не локализуйте строковые константы с внутренними идентификаторами, которые не выводятся пользователю.
К таким строкам не применяйте `НСтр`.

Строковые идентификаторы именуйте по правилам идентификаторов встроенного языка.

#### Пример

```bsl
Возврат "ОперацияВыполненаУспешно";
Оповестить("ЗаписьФайл", Новый Структура("Событие", "ВерсияСохранена"), ФайлСсылка);
```

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

```bsl
Если Статус = "Отгрузка клиентам" Тогда ...
```

#### Правильно

```bsl
Если Статус = "ОтгрузкаКлиентам" Тогда ...
```

Это требование действует и для строковых идентификаторов в текстах запросов и выражениях СКД.

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

#### Правильно

```bsl
РезультатЗагрузки = ЗагрузитьФайлИзИнтернета(...);

Если РезультатЗагрузки = РезультатЗагрузкиУспешно() Тогда
    ...
ИначеЕсли ...
КонецЕсли;

Функция РезультатЗагрузкиУспешно()
    Возврат "Успешно";
КонецФункции
```

Так снимается неоднозначность, когда идентификатор в коде визуально выглядит как пользовательская строка без `НСтр`.

#### 2.

Не используйте в алгоритмах строковые представления объектов и типов.

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

#### 2.1.

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

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

```bsl
Если Строка(ЮрФизЛицо) = "Юридическое лицо" Тогда
```

#### Правильно

```bsl
Если ЮрФизЛицо = ПредопределенноеЗначение("Перечисление.ЮридическоеФизическоеЛицо.ЮридическоеЛицо") Тогда
```

Подробнее: [Работа с предопределенными значениями](https://its.1c.ru/db/v838doc/bookmark/dev/TI000000158).

#### Проверки

[#acc:334](https://v8std.ru/diagnostics/acc/334/)
[#acc:1297](https://v8std.ru/diagnostics/acc/1297/)
[#acc:1298](https://v8std.ru/diagnostics/acc/1298/)
[#acc:1299](https://v8std.ru/diagnostics/acc/1299/)
[#acc:1354](https://v8std.ru/diagnostics/acc/1354/)
#### Источник

https://its.1c.ru/db/v8std#content:764

Не локализуйте строковые константы с внутренними идентификаторами, которые не выводятся пользователю. К таким строкам не применяйте НСтр.

Строка не локализована. Возможно, она видна пользователю. АПК:1297

Нарушен синтаксис описания локализованной строки. Должен быть "НСтр("ru='...'")" или "NStr("en='...'")". АПК:1298

Локализуемая строка начинается или заканчивается непечатаемым символом (например: пробел, таб, перенос). АПК:1299

Локализуемая строка состоит из нелокализуемых символов. АПК:1354

Функция НСтр() использована для локализации внутренних идентификаторов. АПК:334

Строковые константные выражения в коде: требования по локализации #std764


стандарт 765

ID: #std765

# Элементы форм: требования по локализации

#### 1.

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

Для таких значений используйте:

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

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

Изображение: Нелокализуемые строковые значения в реквизите формы (765.image6.png)

```bsl
Если Режим = "Рабочий" Тогда
    Режим = "Демо";
Иначе
    Режим = "Рабочий";
КонецЕсли;
```

#### Правильно

Изображение: Список значений с локализуемыми представлениями (765.image7.png)

#### Правильно

Изображение: Использование перечисления для режима работы (765.image8.png)

```bsl
Если Режим = Перечисления.РежимыРаботы.Рабочий Тогда
    Режим = Перечисления.РежимыРаботы.Демо;
Иначе
    Режим = Перечисления.РежимыРаботы.Рабочий;
КонецЕсли;
```

#### 2.

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

Иначе в команде `Изменить форму` пользователь увидит автоматически сгенерированные заголовки из имен элементов.
Такие заголовки не переводятся: в выгрузку на перевод они попадают как пустые.

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

Изображение: Группа без явного заголовка в свойствах формы (765.image9.png)
Изображение: Автосгенерированный заголовок при изменении формы (765.image10.png)

#### Правильно

Изображение: Заголовок задан явно (765.image11.png)
Изображение: Корректный заголовок при изменении формы (765.image12.png)

Для автоматической расстановки заголовков можно использовать обработку с ИТС:
[Автоформатирование кода и локализации](https://its.1c.ru/db/files/1CITS/EXE/V8Std/АвтоформатированиеКодаИЛокализация/АвтоформатированиеКодаИЛокализация.zip).

#### 3.

Сокращайте количество незначащей информации, которая попадает в локализацию.

#### 3.1.

Удаляйте бессмысленные подсказки у групп форм.
См. стандарт [#std478: Подсказка и проверка заполнения](https://v8std.ru/std/478/)

Это снижает затраты на перевод и исключает лишний шум для пользователя, в том числе в режиме `Изменить форму`.

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

Изображение: Бессмысленные подсказки у групп формы (765.image13.png)
Изображение: Лишние подсказки в пользовательском режиме (765.image14.png)

#### Правильно

Изображение: Подсказки удалены из групп формы (765.image15.png)
Изображение: Форма без лишних подсказок (765.image16.png)

#### 3.2.

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

Для удаления бессмысленных подсказок можно использовать обработку из статьи [#std456: Тексты модулей](https://v8std.ru/std/456/)

#### 4.

Задавайте заголовок для колонок динамического списка, которые:

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

Не полагайтесь на автоматически сгенерированный заголовок по имени или псевдониму.

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

Изображение: Автоматический заголовок колонки динамического списка (765.image2.png)

#### Правильно

Изображение: Явно заданный заголовок колонки динамического списка (765.image3.png)

Примеры, когда заголовок колонки нужно задавать явно:

```sdbl
ВЫБРАТЬ
    Таблица.Поле1 КАК Поле2,
    ВЫРАЗИТЬ(Таблица.Поле1 КАК СТРОКА(100)) КАК Поле3
```

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

Имя колонки задавайте даже если заголовок не выводится в форме.
Пользователь все равно видит эти имена в настройке формы (`Еще` -> `Изменить форму...`).

#### Проверки
[#v8cs:form-dynamic-list-item-title](https://v8std.ru/diagnostics/v8-code-style/form-dynamic-list-item-title/)

#### 5.

Для полей формы со списками выбора всегда устанавливайте свойство `РежимВыбораИзСписка` в значение `Истина`.

Тогда поле выводит корректное локализуемое представление, а не внутреннее значение списка выбора.

#### См. также

#### Проверки
[#v8cs:input-field-list-choice-mode](https://v8std.ru/diagnostics/v8-code-style/input-field-list-choice-mode/)

[#acc:445](https://v8std.ru/diagnostics/acc/445/)
[#acc:446](https://v8std.ru/diagnostics/acc/446/)
[#acc:447](https://v8std.ru/diagnostics/acc/447/)
[#acc:448](https://v8std.ru/diagnostics/acc/448/)
[#acc:464](https://v8std.ru/diagnostics/acc/464/)
#### Источник

https://its.1c.ru/db/v8std#content:765

В реквизит формы присвоена нелокализованная строка. АПК:445

У элемента формы не заполнен заголовок. АПК:446

У элемента формы бессмысленная подсказка. АПК:447

У элемента формы с заполненным списком выбора отключено свойство "Режим выбора из списка". АПК:448

Не заполнен заголовок поля динамического списка. АПК:464

Пустой заголовок для колонок динамического списка (form-dynamic-list-item-title)

В полях форм со списками выбора следует всегда устанавливать свойство РежимВыбораИзСписка в значение Истина (input-field-list-choice-mode)

Тексты модулей #std456

Подсказка и проверка заполнения #std478

Элементы форм: требования по локализации #std765