Кулинарная книга A1sCode · Часть 1

Строительные
блоки

A1sDS и A1sAR — фундамент библиотеки. Они не работают с базой данных напрямую, но используются везде: при создании документов, при загрузке данных из Excel, при формировании параметров запросов. Освоив эти два модуля, вы уже пишете вдвое меньше кода.

A1sDS v2.1.0 A1sAR v2.1 13 рецептов ~160 функций в обоих модулях
A1sDS — Структуры и пары ключ-значение
РЕЦЕПТ 1 · A1sDS

Of — структура за одну строку

⚡ Когда применять: нужно передать несколько параметров в функцию

Самая используемая функция во всей библиотеке. Заменяет классическую конструкцию «объявить структуру → вставить N ключей» одной инлайн-строкой. Принимает до 20 пар ключ-значение. Ключи — строки, значения — что угодно.

✗ Классический 1С
// 5 строк только на структуру
Параметры = Новый Структура;
Параметры.Вставить("Дата",        Дата);
Параметры.Вставить("Организация", Орг);
Параметры.Вставить("Склад",        Склад);
МояФункция(Параметры);
✓ A1sCode
// 1 строка
МояФункция(
  A1sDS.Of(
    "Дата",        Дата,
    "Организация", Орг,
    "Склад",       Склад));
Of · OfFixed · OfKeys — вся линейка фабрик
// ── Of: структура из пар ключ-значение (до 20 пар) ───────────────────────
Шапка = A1sDS.Of(
    "Дата",        '20260201',
    "Организация", МояОрг,
    "Склад",       СкладГП,
    "Комментарий", "Корпус А — февраль");
// → Структура { Дата:'...', Организация:СсылкаОрг, Склад:СсылкаСклад, ... }

// ── OfFixed: то же, но результат — ФиксированнаяСтруктура ────────────────
// Удобно для констант — платформа не даст изменить значения случайно
Режимы = A1sDS.OfFixed(
    "ОсновнойСклад",    СкладОсновной,
    "РезервныйСклад",  СкладРезерв);
// Режимы.ОсновнойСклад = X  ← ошибка: ФиксированнаяСтруктура нельзя изменить

// ── OfKeys: структура из СПИСКА ключей с одним значением ─────────────────
// Применяется для инициализации счётчиков, флагов, накопителей
Счётчики = A1sDS.OfKeys("Создано, Обновлено, Ошибок", 0);
// → { Создано: 0, Обновлено: 0, Ошибок: 0 }

// После обработки строк — накапливаем:
Счётчики.Создано    = Счётчики.Создано + 1;
Счётчики.Обновлено  = Счётчики.Обновлено + 3;

Сообщить("Создано: "   + Счётчики.Создано
       + ", Ошибок: " + Счётчики.Ошибок);
💡
Of и вложенность. Можно передавать результат Of как значение в другой Of — это нормально. Например, для вложенных конфигураций: A1sDS.Of("Фильтр", A1sDS.Of("Склад", СкладСсылка, "Дата", Сегодня)).

РЕЦЕПТ 2 · A1sDS

Defaults — умолчания без перезаписи

⚡ Когда применять: функция с необязательными параметрами, конфигурация из внешней системы

Defaults(SourceStruct, DefaultsStruct) — берёт данные пользователя и добавляет к ним умолчания для тех ключей, которых нет. Ключи из источника всегда побеждают. В отличие от Merge — только дополняет, не перезаписывает.

Defaults — заполнить пропуски умолчаниями
// ── Сценарий: обработка параметров загрузки из внешней системы ───────────
// Пользователь передал только часть настроек — остальное берём по умолчанию

НастройкиПользователя = A1sDS.Of(
    "Организация", МояОрг,    // пользователь задал
    "Дата",        '20260201');    // пользователь задал
// Склад, Валюта, НДС — не задал → возьмём из умолчаний

Умолчания = A1sDS.Of(
    "Организация", ОрганизацияПоУмолчанию,
    "Склад",       СкладОсновной,
    "Валюта",      "RUB",
    "НДС",         Истина);

Итог = A1sDS.Defaults(НастройкиПользователя, Умолчания);
// Итог → { Организация: МояОрг,      ← от пользователя (НЕ перезаписано!)
//           Дата:        '20260201',  ← от пользователя
//           Склад:       СкладОсновной, ← из умолчаний
//           Валюта:      "RUB",       ← из умолчаний
//           НДС:         Истина }     ← из умолчаний

// ── Применение: передаём итоговые параметры в документ ───────────────────
Dok = A1sDocs.Of("ВыпускПродукцииУслуг", Итог);
ℹ️
Defaults vs Merge. Оба объединяют структуры, но логика противоположная. Defaults(A, B) — ключи из A побеждают, B только дополняет. Merge(A, B) — ключи из B перезаписывают A. Правило: «Defaults — для умолчаний, Merge — для обновлений».

РЕЦЕПТ 3 · A1sDS

Merge — объединить с перезаписью

⚡ Когда применять: патч структуры, override параметров, слияние базы и доп. данных

Merge(База, Источник) — возвращает новую структуру, где все ключи из Источника перезаписывают соответствующие ключи Базы. База не мутирует — возвращается копия.

Merge — патч и override
// ── Паттерн: базовая структура документа + override для конкретного случая

БазоваяШапка = A1sDS.Of(
    "Организация", МояОрг,
    "Склад",       СкладОсновной,
    "Валюта",      "RUB",
    "Дата",        ТекущаяДата());

// Для экспортной сделки — переопределяем валюту и склад
ШапкаЭкспорт = A1sDS.Merge(БазоваяШапка, A1sDS.Of(
    "Валюта", "USD",
    "Склад",  СкладЭкспорт));
// ШапкаЭкспорт → { Организация: МояОрг, Склад: СкладЭкспорт,
//                   Валюта: "USD", Дата: ТекДата }
// БазоваяШапка — НЕ изменилась (Merge возвращает новую структуру)

// ── Паттерн DTO-фабрика: функция с необязательным Overrides ──────────────
Функция НовыйВыпуск(Overrides = Неопределено)
    База = A1sDS.Of(
        "Организация", МояОрг,
        "Склад",       СкладГП,
        "Дата",        ТекущаяДата());
    Возврат A1sDS.Merge(База, Overrides); // если Overrides=Неопределено — вернёт копию базы
КонецФункции

// Вызов без параметров — базовые значения
Dok1 = A1sDocs.Of("ВыпускПродукцииУслуг", НовыйВыпуск());

// Вызов с параметрами — база + override
Dok2 = A1sDocs.Of("ВыпускПродукцииУслуг",
    НовыйВыпуск(A1sDS.Of("Дата", '20260301', "Комментарий", "Март")));

РЕЦЕПТ 4 · A1sDS

Pick / Omit — выбрать нужные или исключить лишние

⚡ Когда применять: получили большую структуру из API, нужна только часть полей

Два зеркальных инструмента. Pick — берёт только перечисленные ключи. Omit — берёт всё, кроме перечисленных. Оба принимают ключи через запятую в строке.

Pick · Omit — фильтрация полей структуры
// Допустим, из JSON-API пришла большая структура
ДанныеAPI = A1sDS.Of(
    "id",            "kv-101",
    "Наименование", "Квартира 101",
    "Площадь",      42.5,
    "Этаж",         3,
    "token",         "eyJ0...",     // служебное — нам не нужно
    "_version",      7,              // служебное — нам не нужно
    "Цена",          3500000);

// ── Pick: взять только нужные поля ───────────────────────────────────────
ДляСправочника = A1sDS.Pick(ДанныеAPI, "Наименование, Площадь, Этаж, Цена");
// → { Наименование: "Квартира 101", Площадь: 42.5, Этаж: 3, Цена: 3500000 }
// token и _version — отброшены

// ── Omit: взять всё, кроме указанных ─────────────────────────────────────
ДляСправочника2 = A1sDS.Omit(ДанныеAPI, "id, token, _version");
// → { Наименование: "Квартира 101", Площадь: 42.5, Этаж: 3, Цена: 3500000 }
// Эквивалентно Pick выше, но Pick точнее — Omit добавит любые новые поля из API автоматически

// ── Практика: передать только нужные поля в Ensure ───────────────────────
A1sCatalogs.Ensure(
    "Номенклатура",
    ДанныеAPI.Наименование,
    A1sDS.Omit(ДанныеAPI, "id, token, _version"));

РЕЦЕПТ 5 · A1sDS

Rename / RenameFields — переименовать ключи

⚡ Когда применять: API возвращает английские имена, а реквизиты в 1С — русские

Rename переименовывает ключи одной структуры. RenameFields (новое в v2.1) делает то же самое для массива структур — идеально для подготовки данных перед LoadRows.

Rename · RenameFields — маппинг имён полей
// ── Rename: одна структура ────────────────────────────────────────────────
// JSON из внешнего API: поля с английскими именами
СтрокаAPI = A1sDS.Of(
    "name",     "Квартира 101",
    "area",     42.5,
    "floor",    3,
    "price",    3500000);

// Карта переименования: {старое_имя: "новое_имя"}
КартаПолей = A1sDS.Of(
    "name",  "Наименование",
    "area",  "Площадь",
    "floor", "Этаж",
    "price", "Цена");

ДляСправочника = A1sDS.Rename(СтрокаAPI, КартаПолей);
// → { Наименование: "Квартира 101", Площадь: 42.5, Этаж: 3, Цена: 3500000 }


// ── RenameFields: МАССИВ структур (новое в v2.1) ──────────────────────────
// Пришёл массив JSON-строк, нужно переименовать поля во всех сразу
// и загрузить в ТЧ документа через LoadRows

ДанныеJSON = A1sAR.Of(
    A1sDS.Of("item", "Квартира 101", "qty", 1, "sum", 3500000),
    A1sDS.Of("item", "Квартира 102", "qty", 1, "sum", 3100000),
    A1sDS.Of("item", "Квартира 103", "qty", 1, "sum", 4400000));

// Схема один раз — описываем ДО цикла
// Поля вне схемы копируются как есть (qty → qty если не указано)
Схема = A1sDS.Of(
    "item", "Номенклатура",  // item → Номенклатура
    "qty",  "Количество",    // qty  → Количество
    "sum",  "Сумма");        // sum  → Сумма

ПодготовленныеСтроки = A1sDS.RenameFields(ДанныеJSON, Схема);
// → массив структур с русскими именами:
//   [{ Номенклатура: "Квартира 101", Количество: 1, Сумма: 3500000 }, ...]

// Загружаем в ТЧ документа
A1sDocs.LoadRows(Dok, "Продукция", ПодготовленныеСтроки);
💡
RenameFields + LoadRows — стандартный конвейер. Объявляете схему один раз вне цикла, передаёте весь массив. Цикл загрузки не знает об именах полей источника — при изменении схемы API меняете только схему, а не весь цикл.

РЕЦЕПТ 6 · A1sDS

AddIf — добавить поле по условию

⚡ Когда применять: структура формируется динамически, некоторые поля нужны не всегда

AddIf(Структура, Ключ, ЗначениеЕслиИстина, Условие) — добавляет ключ в структуру только если условие выполнено. Возвращает ту же структуру — удобно для инлайн-цепочек.

AddIf — условная сборка структуры
// ── Сценарий: параметры фильтра формируются в зависимости от флагов ───────

Фильтр = A1sDS.Of("Организация", МояОрг);  // обязательное поле

// Добавляем склад только если он задан в параметрах формы
A1sDS.AddIf(Фильтр, "Склад", Склад, ЗначениеЗаполнено(Склад));

// Добавляем период только если включён флаг "ПоПериоду"
A1sDS.AddIf(Фильтр, "НачалоПериода", НачалоПериода, ФильтрПоПериоду);
A1sDS.AddIf(Фильтр, "КонецПериода",  КонецПериода,  ФильтрПоПериоду);

// Добавляем комментарий с альтернативным значением при ложном условии
A1sDS.AddIf(Фильтр, "Режим",
    "Детальный",     // если ДетальныйРежим = Истина
    ДетальныйРежим,
    "Краткий");     // иначе — "Краткий"

// ── Всё вместе, инлайн-стиль ─────────────────────────────────────────────
Параметры = A1sDS.Of("Организация", МояОрг);
A1sDS.AddIf(Параметры, "Склад",    Склад,    ЗначениеЗаполнено(Склад));
A1sDS.AddIf(Параметры, "Контрагент", Контрагент, ЗначениеЗаполнено(Контрагент));
ДокументыПоФильтру = A1sDocs.Refs("РеализацияТоваровУслуг",
    "Организация = &Организация", Параметры);

РЕЦЕПТ 7 · A1sDS

HasKeys · GetKeys · GroupBy — анализ данных

⚡ Когда применять: валидация входящих данных, агрегация без запроса к БД

Небольшие, но полезные инструменты. HasKeys — проверить что все обязательные поля есть. GroupBy — сгруппировать массив структур и посчитать суммы.

HasKeys · GetKeys · GroupBy
// ── HasKeys: валидация обязательных полей перед загрузкой ─────────────────
СтрокаJSON = A1sDS.Of("Наименование", "Кв 101", "Площадь", 42.5);
// Поля "Этаж" и "Цена" отсутствуют

Если НЕ A1sDS.HasKeys(СтрокаJSON, "Наименование, Площадь, Цена") Тогда
    Сообщить("Ошибка: не заполнены обязательные поля (Цена)");
    Возврат;
КонецЕсли;

// ── GetKeys: перебрать все ключи структуры ────────────────────────────────
Ключи = A1sDS.GetKeys(СтрокаJSON);  // → ["Наименование", "Площадь"]
Сообщить("Поля: " + A1sAR.Join(Ключи, ", "));  // "Поля: Наименование, Площадь"

// ── GroupBy: сгруппировать строки выпуска по этажу и посчитать суммы ──────
СтрокиВыпуска = A1sAR.Of(
    A1sDS.Of("Этаж", "3", "Сумма", 3500000),
    A1sDS.Of("Этаж", "3", "Сумма", 3100000),
    A1sDS.Of("Этаж", "4", "Сумма", 4400000),
    A1sDS.Of("Этаж", "4", "Сумма", 5100000));

ИтогиПоЭтажам = A1sDS.GroupBy(СтрокиВыпуска, "Этаж", "Сумма");
// → { "3": 6600000, "4": 9500000 }
// Без запроса к БД, без ТЗ.Итог() — просто из массива структур

Сообщить("Этаж 3: " + ИтогиПоЭтажам["3"]);  // 6600000
Сообщить("Этаж 4: " + ИтогиПоЭтажам["4"]);  // 9500000
A1sAR — Массивы
РЕЦЕПТ 8 · A1sAR

Of — массив за одну строку

⚡ Когда применять: нужно передать список значений в функцию инлайн

Зеркало A1sDS.Of, но для массивов. Принимает до 40 элементов любого типа. Именно через него удобно передавать списки имён в EnsureBatch, PickByName, PostAll.

✗ Классический 1С
Имена = Новый Массив;
Имена.Добавить("ПРОЖИВАНИЕ");
Имена.Добавить("ПИТАНИЕ");
Имена.Добавить("ПРОЧЕЕ");
МояФункция(Имена);
✓ A1sCode
МояФункция(
  A1sAR.Of(
    "ПРОЖИВАНИЕ",
    "ПИТАНИЕ",
    "ПРОЧЕЕ"));
Of · OfN — создание массивов
// ── Of: элементы любого типа ──────────────────────────────────────────────
Числа   = A1sAR.Of(1, 2, 3, 4, 5);
Имена   = A1sAR.Of("ПРОЖИВАНИЕ", "ПИТАНИЕ", "ПРОЧЕЕ");
Ссылки  = A1sAR.Of(Ном1, Ном2, Ном3);    // ссылки тоже работают
Строки  = A1sAR.Of(               // массив структур — для AddRows
    A1sDS.Of("Ном", Ном1, "Кол", 1),
    A1sDS.Of("Ном", Ном2, "Кол", 2));

// Флаг ТолькоУникальные — убрать дубликаты при создании
УникальныеИмена = A1sAR.Of("А", "Б", "А", "В", "Б", /*ТолькоУникальные=*/ Истина);
// → ["А", "Б", "В"]

// ── OfN: массив заданного размера с одинаковым значением ─────────────────
Нули    = A1sAR.OfN(5, 0);         // [0, 0, 0, 0, 0]
Флаги   = A1sAR.OfN(10, Ложь);    // [Ложь, Ложь, ... × 10]
Буфер   = A1sAR.OfN(100, "");     // 100 пустых строк — для заполнения в цикле

РЕЦЕПТ 9 · A1sAR

Concatenate · Union · Difference — операции над множествами

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

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

Concatenate · Union · Difference · Intersection
// ── Concatenate: объединить несколько массивов ────────────────────────────
ВсеНом = A1sAR.Concatenate(НомДок1, НомДок2, НомДок3);
// Принимает до 8 массивов + флаг ТолькоУникальные

УникВсеНом = A1sAR.Concatenate(НомДок1, НомДок2, НомДок3, /*ТолькоУникальные*/ Истина);

// ── Union: объединение — уникальные элементы из всех массивов ─────────────
// Эквивалентно Concatenate с ТолькоУникальные=Истина, но читается явнее
ОбщаяНоменклатура = A1sAR.Union(НомДок1, НомДок2, НомДок3);

// ── Difference: что выпустили, но ещё не реализовали ─────────────────────
ВыпущеннаяНом   = A1sAR.Of(Ном101, Ном102, Ном103, Ном201);
РеализованнаяНом = A1sAR.Of(Ном101, Ном201);

НевыпущенноеОстаток = A1sAR.Difference(ВыпущеннаяНом, РеализованнаяНом);
// → [Ном102, Ном103] — то что выпустили, но не реализовали

// ── Intersection: пересечение — что есть в обоих ─────────────────────────
ОбщиеПозиции = A1sAR.Intersection(ВыпущеннаяНом, РеализованнаяНом);
// → [Ном101, Ном201]

РЕЦЕПТ 10 · A1sAR

PickFilled · PickRefs · RemoveDuplicates — очистка данных

⚡ Когда применять: данные пришли из формы или Excel и могут содержать пустые значения и дубликаты

Три функции для очистки «сырых» данных до того, как передать их в документ или справочник. Убрать пустые, убрать дубликаты, оставить только ссылки.

PickFilled · PickRefs · PickNotNull · RemoveDuplicates
// ── Сценарий: пользователь выбрал несколько номенклатур на форме ──────────
// Список может содержать пустые ссылки и дубликаты

ВыборПользователя = A1sAR.Of(
    Ном1, Неопределено, Ном2, Ном1,         // дубль Ном1
    A1sCatalogs.Empty("Номенклатура"),       // пустая ссылка
    Ном3, Неопределено);

// Шаг 1: убрать Неопределено и пустые ссылки
БезПустых = A1sAR.PickFilled(ВыборПользователя);
// → [Ном1, Ном2, Ном1, Ном3]  (Неопределено и пустые ссылки убраны)

// Шаг 2: убрать дублирующиеся ссылки
ЧистыйСписок = A1sAR.RemoveDuplicates(БезПустых);
// → [Ном1, Ном2, Ном3]

// ── Всё в одну строку: RemoveDuplicates(PickFilled(...)) ─────────────────
ГотовыйСписок = A1sAR.RemoveDuplicates(
    A1sAR.PickFilled(ВыборПользователя));

// ── PickRefs: оставить только ссылки (убирает строки, числа, Неопределено)
// Используется когда массив содержит разнотипные значения
СмешанныйМассив = A1sAR.Of(Ном1, "текст", Ном2, 42, Ном3);
ТолькоСсылки    = A1sAR.PickRefs(СмешанныйМассив);
// → [Ном1, Ном2, Ном3]  (строки и числа убраны)

// ── PickNotNull: оставить всё кроме Неопределено (включая пустые ссылки)
// Когда пустая ссылка — валидное значение, но Неопределено — нет
БезНеопределено = A1sAR.PickNotNull(ВыборПользователя);
⚠️
PickFilled vs PickNotNull. PickFilled убирает и Неопределено, и пустые ссылки, и пустые строки (ЗначениеЗаполнено вернёт Ложь для всех). PickNotNull убирает только Неопределено — пустая ссылка пройдёт. Для обычной очистки входных данных используйте PickFilled.

РЕЦЕПТ 11 · A1sAR

Chunk — разбить на пачки для пакетной обработки

⚡ Когда применять: нужно обработать 1000+ записей, но лучше порциями по 100–500

Chunk(Array, Size) разбивает массив на подмассивы заданного размера. Последний кусок может быть меньше — это нормально. Незаменим для массовых загрузок.

Chunk — пакетная загрузка
// ── Сценарий: загрузить 500 квартир в справочник, порциями по 100 ─────────
// Зачем пачками? Чтобы не держать транзакцию открытой слишком долго

ВсеКвартиры = /* ... массив из 500 строк из Excel ... */;
Сообщить("Всего позиций: " + ВсеКвартиры.Количество());

// Разбиваем на пачки по 100
Пачки = A1sAR.Chunk(ВсеКвартиры, 100);
// → [[строки 1-100], [строки 101-200], ..., [строки 401-500]]
// Каждый элемент Пачки — это массив строк из Excel

НомерПачки = 0;
Для Каждого Пачка Из Пачки Цикл
    НомерПачки = НомерПачки + 1;
    Сообщить("Пачка " + НомерПачки + ": " + Пачка.Количество() + " записей");

    Для Каждого СтрокаExcel Из Пачка Цикл
        A1sCatalogs.EnsureUpdate(
            "Номенклатура",
            СтрокаExcel.Наименование,
            A1sDS.Pick(СтрокаExcel, "Площадь, Этаж, Цена"));
    КонецЦикла;

    // Пауза между пачками (опционально, для больших баз)
    ОбработкаПрерыванияПользователя();
КонецЦикла;

Сообщить("✓ Загружено " + ВсеКвартиры.Количество() + " позиций в "
    + Пачки.Количество() + " пачках");

РЕЦЕПТ 12 · A1sAR

First · Last · Contains · IndexOf — доступ без индексов

⚡ Когда применять: нужен первый/последний элемент без [0] и [N-1], проверить вхождение

Маленькие функции, которые убирают типичные ошибки «выход за границы массива» и делают код более читаемым.

First · Last · Contains · IndexOf · IsEmpty
ВыпускиЗаМесяц = A1sDocs.AllInPeriod("ВыпускПродукцииУслуг", '20260201', '20260228');

// ── Безопасный доступ — не упадёт на пустом массиве ──────────────────────
ПервыйВыпуск    = A1sAR.First(ВыпускиЗаМесяц);   // Неопределено если пустой
ПоследнийВыпуск = A1sAR.Last(ВыпускиЗаМесяц);    // Неопределено если пустой

Если ПервыйВыпуск = Неопределено Тогда
    Сообщить("За февраль выпусков нет");
КонецЕсли;

// vs классический — требует проверки размера вручную:
// Если ВыпускиЗаМесяц.Количество() > 0 Тогда
//     ПервыйВыпуск = ВыпускиЗаМесяц[0];   ← IndexOutOfBounds если забыть проверку
// КонецЕсли;

// ── Contains: проверить вхождение ────────────────────────────────────────
ДозволенныеСклады = A1sAR.Of(СкладОсновной, СкладРезерв, СкладЭкспорт);

Если НЕ A1sAR.Contains(ДозволенныеСклады, ВыбранныйСклад) Тогда
    ВызватьИсключение "Склад не входит в список разрешённых";
КонецЕсли;

// ── IsEmpty: проверить что массив пустой ─────────────────────────────────
Если A1sAR.IsEmpty(ВыпускиЗаМесяц) Тогда
    Сообщить("Нет документов за период");
    Возврат;
КонецЕсли;

// ── IndexOf: найти позицию элемента (−1 если не найден) ──────────────────
ПозицияВыпуска = A1sAR.IndexOf(ВыпускиЗаМесяц, КонкретныйВыпуск);
Если ПозицияВыпуска >= 0 Тогда
    Сообщить("Найден на позиции: " + ПозицияВыпуска);
КонецЕсли;

РЕЦЕПТ 13 · A1sAR

AddIf · Join — условное добавление и склейка

⚡ Когда применять: строим список условно, нужно вывести список в сообщении

AddIf добавляет элемент в массив только при выполнении условия. Join склеивает элементы через разделитель — аналог СтрСоединить, но для массивов любого типа.

AddIf · Join — условная сборка и форматирование
// ── AddIf: собрать список ошибок условно ──────────────────────────────────
Ошибки = Новый Массив;

A1sAR.AddIf(Ошибки, "Не заполнена Организация",  НЕ ЗначениеЗаполнено(Организация));
A1sAR.AddIf(Ошибки, "Не заполнен Склад",       НЕ ЗначениеЗаполнено(Склад));
A1sAR.AddIf(Ошибки, "ТЧ пустая",               Dok.Продукция.Количество() = 0);

Если НЕ A1sAR.IsEmpty(Ошибки) Тогда
    ВызватьИсключение "Ошибки заполнения: " + A1sAR.Join(Ошибки, "; ");
    // → "Ошибки заполнения: Не заполнена Организация; ТЧ пустая"
КонецЕсли;

// ── AddIf с альтернативным значением ─────────────────────────────────────
СтатусыДокументов = Новый Массив;
Для Каждого Ссылка Из ВыпускиЗаМесяц Цикл
    A1sAR.AddIf(СтатусыДокументов,
        "✓ проведён",     // если проведён
        A1sDocs.IsPosted(Ссылка),
        "✗ не проведён"); // иначе
КонецЦикла;

// ── Join: вывести список в одну строку ───────────────────────────────────
ИменаНом = A1sAR.Of("Квартира 101", "Квартира 102", "Квартира 103");
Сообщить("Загружено: " + A1sAR.Join(ИменаНом, ", "));
// → "Загружено: Квартира 101, Квартира 102, Квартира 103"

// Join работает с любыми типами — числа, даты тоже преобразуются в строку
СуммыВСтроку = A1sAR.Join(A1sAR.Of(3500000, 3100000, 4400000), " + ");
// → "3 500 000 + 3 100 000 + 4 400 000"
💡
Паттерн «сбор ошибок». AddIf + IsEmpty + Join — классическая тройка для валидации перед записью. Соберите все ошибки в массив, проверьте пустоту, выведите одним сообщением. Намного лучше, чем серия Если ... ВызватьИсключение вперемешку с логикой.
Справочник функций

A1sDS — все экспортируемые функции

Функция Сигнатура Что делает
Of Of(K1,V1, K2,V2 ...) Структура из пар ключ-значение (до 20)
OfFixed OfFixed(K1,V1 ...) Неизменяемая (ФиксированнаяСтруктура)
OfKeys OfKeys(Keys, Default) Структура из списка ключей с одним значением
Zip Zip(МассивКлючей, МассивЗнач) Структура из двух параллельных массивов
Pick Pick(Struct, "K1,K2") Выбрать только перечисленные ключи
Omit Omit(Struct, "K1,K2") Исключить перечисленные ключи
Rename Rename(Struct, MapStruct) Переименовать ключи по карте
RenameFieldsv2.1 RenameFields(МассивСтр, Схема) Переименовать ключи в массиве структур
Defaults Defaults(Source, Defaults) Дополнить только отсутствующие ключи
Merge Merge(Base, Source) Слить: Source перезаписывает Base
AddIf AddIf(Struct, Key, Val, Cond) Добавить ключ по условию
HasKey HasKey(Struct, Key) → Bool Есть ли ключ
HasKeys HasKeys(Struct, "K1,K2") → Bool Есть ли все перечисленные ключи
IsEmpty IsEmpty(Struct) → Bool Структура пустая?
GetKeys GetKeys(Struct) → Array Массив имён ключей
GetValues GetValues(Struct) → Array Массив значений
Equals Equals(S1, S2) → Bool Глубокое сравнение двух структур
GroupBy GroupBy(АррСтрукт, ГрупКлюч, СумКлюч) Группировка массива структур с суммированием
FlattenKeys FlattenKeys(Nested, Sep="_") Вложенная структура → плоская
NestKeys NestKeys(Flat, Sep="_") Плоская → вложенная
DeepCopy DeepCopy(Struct) Глубокое копирование
GetOrInsert GetOrInsert(Struct, Key, Default) Получить или вставить дефолт
ToFixed ToFixed(Struct) Преобразовать в ФиксированнаяСтруктура
Sanitize Sanitize(Data) Убрать Неопределено и пустые строки
ToJSON ToJSON(Struct) → String Сериализовать в JSON
On On(Struct?) → Fluent Fluent-обёртка для цепочек
SelfTest SelfTest() → Bool Самотест модуля

A1sAR — все экспортируемые функции

Функция Сигнатура Что делает
Of Of(V1, V2 ...V40, Unique?) Массив из значений (до 40)
OfN OfN(Size, Default) Массив N штук с одним значением
Chunk Chunk(Array, Size) → Array[] Разбить на подмассивы заданного размера
Flatten Flatten(Array) → Array Массив массивов → плоский массив
Insert Insert(Arr, Idx, Val) Вставить элемент в позицию
RemoveAt RemoveAt(Arr, Idx) Удалить элемент по индексу
Sort Sort(Arr) → Arr Сортировать по возрастанию
Reverse Reverse(Arr) → Arr Обратить порядок
Split Split(Arr, Value, Include?) Разделить массив по значению-разделителю
SplitAt SplitAt(Arr, Index) Разрезать по индексу на два
Concatenate Concatenate(A1..A8, Unique?) Объединить до 8 массивов
RemoveDuplicates RemoveDuplicates(Arr) Убрать дубликаты
Union Union(A1..A8) Объединение уникальных из всех
Intersection Intersection(A1..A8) Пересечение: только общие элементы
Difference Difference(A1, A2..A8) Разность: есть в A1, нет в остальных
PickByType PickByType(Arr, Type) Только элементы указанного типа
OmitByType OmitByType(Arr, Type) Всё кроме указанного типа
PickRefs PickRefs(Arr) Только ссылки
PickFilled PickFilled(Arr) Только заполненные значения
PickNotNull PickNotNull(Arr) Всё кроме Неопределено
ConvertTo ConvertTo(Arr, Type, Default?) Привести все элементы к типу
First First(Arr) → Val|Undefined Первый элемент или Неопределено
Last Last(Arr) → Val|Undefined Последний элемент или Неопределено
Contains Contains(Arr, Val) → Bool Содержит ли значение
IndexOf IndexOf(Arr, Val) → Num Индекс первого вхождения (−1 если нет)
Join Join(Arr, Sep) → String Склеить элементы через разделитель
IsEmpty IsEmpty(Arr) → Bool Массив пустой?
AddIf AddIf(Arr, Val, Cond, ElseVal?) Добавить элемент по условию
Equals Equals(A1, A2) → Bool Поэлементное сравнение
ToJSON ToJSON(Arr) → String Сериализовать в JSON
Sanitize Sanitize(Arr) Очистить от мусорных значений
On On(Arr?) → Fluent Fluent-обёртка A1sDP_AR