A1sCode библиотека 1С

Быстрый старт

A1sCode Assistant for 1C: Open Assistant. Может требоваться VPN для доступа к OpenAI.
Шпаргалки: быстрые мини‑введения по библиотеке и по 1С.

Что нужно до запуска и где взять файлы.

  • 1С: 8.3.2x+; файлы в UTF‑8.
  • Права: на чтение справочников/документов; при работе с ИИ — доступ в Интернет.
  • Импортируйте конфигурацию (.cf) и подключите модули A1sQ, A1sS в своём общем модуле.

Открыть «Рецепты» → Перейти в «Библиотеку» →

0) Требования и установка

Если используете внешние модели/сервисы — храните ключи безопасно и не логируйте их.


// Пример: считываем ключ из защищённого хранилища и настраиваем ваш клиент
Функция КлючИИ() Экспорт
    // Верните ключ тем способом, который принят у вас (Константы, БезопасноеХранилище и т.п.)
    Возврат ОбщегоНазначения.ПолучитьКлюч("OPENAI_API_KEY");
КонецФункции

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

0.1) Внешние сервисы / ключи (опционально)

  • Пишите в журнал регистрации при ошибках: ЗаписьЖурналаРегистрации(...).
  • Для быстрых заметок используйте A1sS.Print(...).

Процедура ЛогДемо() Экспорт
    A1sS.Print("Старт демо");
    Попытка
        // ваш код
    Исключение
        ЗаписьЖурналаРегистрации("A1sCode: Ошибка", УровеньЖурналаРегистрации.Ошибка, Неопределено, Неопределено, ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

0.2) Логи и отладка

  • Скачайте свежие .bsl и замените соответствующие модули.
  • После обновления: пересоберите конфигурацию и повторите «Проверку установки».

0.3) Обновление библиотеки

  • Не логируйте персональные данные и секреты.
  • Ограничивайте права пользователя, от имени которого выполняются запросы.
  • Для ИИ‑запросов фильтруйте входные данные и ставьте таймауты.

0.4) Безопасность

  1. Импортируйте конфигурацию и обновите базу.
  2. Подключите модули (напр., A1sQ, A1sS).
  3. Выполните проверку ниже и перейдите к примерам.
Подсказка: любой блок кода копируется левым кликом.

1) Проверка установки (с Попыткой)

Быстрый тест доступности модулей и журналирования ошибок.


Процедура ПроверкаУстановкиA1sCode() Экспорт
    Попытка
        A1sS.Print("A1sCode установлен ✅");
    Исключение
        ЗаписьЖурналаРегистрации("A1sCode: Проверка установки",
            УровеньЖурналаРегистрации.Ошибка, Неопределено, Неопределено, ОписаниеОшибки());
        Сообщить("A1sCode: ошибка установки — см. Журнал регистрации");
    КонецПопытки;
КонецПроцедуры

2) Одно значение через ValueQ

Получаем ссылку текущего пользователя по UID без промежуточных объектов.


Функция СсылкаТекущегоПользователя() Экспорт
    UID = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
    Возврат A1sQ.ValueQ(
        A1sQ.QT(
            "ПЕРВЫЕ 1 Ссылка",
            "Справочник.Пользователи",
            "ИдентификаторПользователяИБ = &UID"
        ),
        UID
    );
КонецФункции

Процедура УстановитьТекПользователяВСеанс() Экспорт
    Ссылка = СсылкаТекущегоПользователя();
    ПараметрыСеанса.ТекущийПользователь = ?(ЗначениеЗаполнено(Ссылка), Ссылка, Справочники.Пользователи.ПустаяСсылка());
КонецПроцедуры

3) Ещё одно значение через ValueQ

Берём наименование того же пользователя. Полезно для заголовков/логов.


Функция ИмяТекущегоПользователя() Экспорт
    UID = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
    Возврат A1sQ.ValueQ(
        A1sQ.QT(
            "ПЕРВЫЕ 1 Наименование",
            "Справочник.Пользователи",
            "ИдентификаторПользователяИБ = &UID"
        ),
        UID
    );
КонецФункции

4) Проверка существования через ExistsQ

Возвращает булево, быстро и без выборок.


Функция ЕстьПользовательСЛогином(Логин) Экспорт
    Возврат A1sQ.ExistsQ(
        A1sQ.QT(
            "ПЕРВЫЕ 1 Ссылка",
            "Справочник.Пользователи",
            "Наименование = &ИмяИлиЛогин"
        ),
        Логин
    );
КонецФункции

5) Табличный результат: поиск по маске

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


Функция НайтиПользователейПоИмени(Шаблон) Экспорт
    Рез = A1sQ.ExecuteQ(
        A1sQ.QT(
            "Ссылка, Наименование",
            "Справочник.Пользователи",
            "Наименование ПОДОБНО &Шаблон"
        ),
        "*" + Шаблон + "*"
    );
    Возврат Рез.Выгрузить(); // ТаблицаЗначений
КонецФункции

6) Даты, сортировка и лимит

Фильтруем документы по периоду, сортируем по дате, берём верхние строки.


Функция ПоследниеЗаказы(Начало, Конец, Лимит) Экспорт
    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "ПЕРВЫЕ &Лим Количество, Ссылка, Дата, Номер, Контрагент",
            "Документ.ЗаказПокупателя",
            "Дата МЕЖДУ &Нач И &Конец
             |УПОРЯДОЧИТЬ ПО Дата УБЫВ"
        ),
        Новый Структура("Лим,Нач,Конец", Лимит, Начало, Конец)
    );
КонецФункции

7) Соединение: строки заказа + номенклатура

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


Функция СтрокиЗаказаСНаименованиями(СсылкаЗаказа) Экспорт
    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "Т.Ссылка КАК Заказ, Т.Номенклатура, Ном.Наименование КАК Товар,
             |Т.Количество, Т.Цена, (Т.Количество * Т.Цена) КАК Сумма",
            "Документ.ЗаказПокупателя.Товары КАК Т
             |ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Ном
             |ПО Т.Номенклатура = Ном.Ссылка",
            "Т.Ссылка = &Заказ"
        ),
        СсылкаЗаказа
    );
КонецФункции

8) Агрегация: суммы по номенклатуре

Суммируем количество и сумму по позициям заказа.


Функция ИтогиПоНоменклатуреВЗаказе(СсылкаЗаказа) Экспорт
    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "Т.Номенклатура,
             |СУММА(Т.Количество) КАК Количество,
             |СУММА(Т.Количество * Т.Цена) КАК Сумма",
            "Документ.ЗаказПокупателя.Товары КАК Т",
            "Т.Ссылка = &Заказ
             |СГРУППИРОВАТЬ ПО Т.Номенклатура"
        ),
        СсылкаЗаказа
    );
КонецФункции

9) Шаблон «SafeQ»: безопасное выполнение запроса

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


Функция SafeQ(ТекстЗапроса, Парам) Экспорт
    Попытка
        Возврат A1sQ.ExecuteQ(ТекстЗапроса, Парам);
    Исключение
        ЗаписьЖурналаРегистрации("A1sQ: Ошибка запроса",
            УровеньЖурналаРегистрации.Ошибка, Неопределено, Неопределено, ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

Что дальше?

FAQ / Ошибки

  • Модули не видны. Проверьте, что общий модуль подключён и доступен на сервере/клиенте.
  • Кодировка. Все файлы — UTF-8.
  • Внешние ссылки не открываются. Попробуйте другой браузер, сеть или VPN.

10) До → После: ValueQ вместо FirstRow

Когда нужен один скаляр — короче и быстрее через ValueQ.

До: FirstRow + ExecuteQ

Функция СсылкаТекПользователя_Do() Экспорт
    UID = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
    row = A1sQ.FirstRow(
        A1sQ.ExecuteQ(
            A1sQ.QT(
                "ПЕРВЫЕ 1 Ссылка",
                "Справочник.Пользователи",
                "ИдентификаторПользователяИБ = &UID"
            ),
            UID
        )
    );
    Возврат ?(row = Неопределено, Неопределено, row.Ссылка);
КонецФункции
После: лаконично через ValueQ

Функция СсылкаТекПользователя_Posle() Экспорт
    UID = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
    Возврат A1sQ.ValueQ(
        A1sQ.QT(
            "ПЕРВЫЕ 1 Ссылка",
            "Справочник.Пользователи",
            "ИдентификаторПользователяИБ = &UID"
        ),
        UID
    );
КонецФункции

11) Пагинация: страница + размер

Используем УПОРЯДОЧИТЬ ПО, затем ИСКЛЮЧИТЬ ПЕРВЫЕ (offset) и ПЕРВЫЕ (limit).


Функция ЗаказыСтраница(Страница, Размер) Экспорт
    Если Страница < 1 Тогда Страница = 1; КонецЕсли;
    Если Размер < 1 Тогда Размер = 20; КонецЕсли;
    Пропустить = (Страница - 1) * Размер;

    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "ПЕРВЫЕ &Лим Ссылка, Дата, Номер, Контрагент
             |ИСКЛЮЧИТЬ ПЕРВЫЕ &Проп",
            "Документ.ЗаказПокупателя",
            "УПОРЯДОЧИТЬ ПО Дата УБЫВ"
        ),
        Новый Структура("Лим,Проп", Размер, Пропустить)
    );
КонецФункции

12) Шпаргалка: QT(...) и популярные условия

Конструктор QT(SELECT, FROM, WHERE) собирает текст запроса. Несколько приёмов:


// Равенство + параметр по позиции
A1sQ.QT("ПЕРВЫЕ 1 Ссылка", "Справочник.Номенклатура", "Код = &Код");

// ПОДОБНО (маска)
A1sQ.QT("Ссылка, Наименование", "Справочник.Номенклатура", "Наименование ПОДОБНО &Шаблон");

// МЕЖДУ датами
A1sQ.QT("Ссылка, Дата, Номер", "Документ.РеализацияТоваровУслуг", "Дата МЕЖДУ &Нач И &Конец");

// В множестве
A1sQ.QT("Ссылка, Наименование", "Справочник.Номенклатура", "Ссылка В(&Список)");

// В ИЕРАРХИИ (группа + подчинённые)
A1sQ.QT("Ссылка, Наименование", "Справочник.Номенклатура", "В ИЕРАРХИИ &Группа");

// ЕСТЬNULL (подмена NULL значением)
A1sQ.QT("ЕСТЬNULL(Артикул, "—") КАК Артикул", "Справочник.Номенклатура", "");

// Упорядочивание
A1sQ.QT("Ссылка, Дата, Номер", "Документ.ПоступлениеТоваровУслуг", "УПОРЯДОЧИТЬ ПО Дата УБЫВ");

// Агрегация
A1sQ.QT("Номенклатура, СУММА(Количество) КАК Кол", "Документ.ЗаказПокупателя.Товары", "СГРУППИРОВАТЬ ПО Номенклатура");

13) Профилирование: время и объём данных

Шаблон замера времени выполнения и количества строк результата.


Процедура ПрофильЗапроса(Шаблон) Экспорт
    Нач = ТекущаяДата();
    Рез = A1sQ.ExecuteQ(
        A1sQ.QT(
            "Ссылка, Наименование",
            "Справочник.Пользователи",
            "Наименование ПОДОБНО &Шаблон
             |УПОРЯДОЧИТЬ ПО Наименование"
        ),
        "*" + Шаблон + "*"
    );
    Таб = Рез.Выгрузить();
    Мс = РазностьДат(ТекущаяДата(), Нач, ВидИнтервала.Миллисекунда);
    A1sS.Print("Время (мс): " + Формат(Мс, "ЧГ=0") + "; Строк: " + Формат(Таб.Количество(), "ЧГ=0"));
КонецПроцедуры

14) До → После: ExistsQ вместо выборки строки

Если нужно только «есть/нет» — используйте ExistsQ, он не тянет данные.

До: ПЕРВЫЕ 1 + FirstRow

Функция ЕстьПользователь_Do(Логин) Экспорт
    row = A1sQ.FirstRow(
        A1sQ.ExecuteQ(
            A1sQ.QT("ПЕРВЫЕ 1 Ссылка", "Справочник.Пользователи", "Наименование = &Имя"),
            Логин
        )
    );
    Возврат row <> Неопределено;
КонецФункции
После: лаконично через ExistsQ

Функция ЕстьПользователь_Posle(Логин) Экспорт
    Возврат A1sQ.ExistsQ(
        A1sQ.QT("ПЕРВЫЕ 1 Ссылка", "Справочник.Пользователи", "Наименование = &Имя"),
        Логин
    );
КонецФункции

15) Пагинация с «якорем» (Keyset)

Надёжнее offset: быстро и без «дыр»/дубликатов при вставках между страницами.


// Возвращает следующую страницу заказов "после" якоря (Дата, Ссылка), по убыванию даты.
Функция ЗаказыПосле(LastDate, LastRef, Лимит) Экспорт
    // Направление сортировки и условие должны совпадать
    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "ПЕРВЫЕ &Лим Ссылка, Дата, Номер, Контрагент",
            "Документ.ЗаказПокупателя",
            "(Дата < &Дат)
             |ИЛИ (Дата = &Дат И Ссылка < &Ссыл)
             |УПОРЯДОЧИТЬ ПО Дата УБЫВ, Ссылка УБЫВ"
        ),
        Новый Структура("Лим,Дат,Ссыл", Лимит, LastDate, LastRef)
    );
КонецФункции

// Первая страница (без якоря) — просто используйте &Лим и тот же ORDER BY.
Функция ЗаказыПервая(Лимит) Экспорт
    Возврат A1sQ.ExecuteQ(
        A1sQ.QT(
            "ПЕРВЫЕ &Лим Ссылка, Дата, Номер, Контрагент",
            "Документ.ЗаказПокупателя",
            "УПОРЯДОЧИТЬ ПО Дата УБЫВ, Ссылка УБЫВ"
        ),
        Новый Структура("Лим", Лимит)
    );
КонецФункции

16) Шпаргалка параметров: один, структура, список

Как передавать параметры в A1sQ.* корректно и удобно.


// 1) Один параметр (позиционный)
A1sQ.ExecuteQ(
    A1sQ.QT("ПЕРВЫЕ 1 Ссылка", "Справочник.Номенклатура", "Код = &Код"),
    "000123"
);

// 2) Несколько параметров — именованно через Структура
Парам = Новый Структура("Нач,Конец,Статус", НачалоПериода, КонецПериода, Перечисления.СтатусыЗаказов.Подтвержден);
A1sQ.ExecuteQ(
    A1sQ.QT("Ссылка, Дата, Номер", "Документ.ЗаказПокупателя", "Дата МЕЖДУ &Нач И &Конец И Статус = &Статус"),
    Парам
);

// 3) Множество значений (IN) — Массив/ТаблицаЗначений/СписокЗначений
Список = Новый Массив; Список.Добавить(СпрНом["0001"]); Список.Добавить(СпрНом["0002"]);
A1sQ.ExecuteQ(
    A1sQ.QT("Ссылка, Наименование", "Справочник.Номенклатура", "Ссылка В(&Список)"),
    Новый Структура("Список", Список)
);

// 4) Комбинация позиционного и структурного — избегайте. Лучше всё через Структура для читаемости.