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

Цели дня

Дымовые проверки (smoke)

Минимальный тест даёт ответ: «жив» ли источник данных, корректны ли колонки и параметры.


Процедура SmokeQ(ТекстQ, П1 = Неопределено, П2 = Неопределено) Экспорт
    // Забираем только одну строку — дёшево и информативно
    ТекстПроба = "
    |ВЫБРАТЬ ПЕРВЫЕ 1
    |    * 
    |ИЗ (" + ТекстQ + ") КАК Q";
    Попытка
        Таб = A1sQ.Unload(ТекстПроба, П1, П2);
        A1sLog.Info("Day7", "Smoke OK: колонок=" + Таб.Колонки.Количество() + ", строк=" + Таб.Количество());
    Исключение
        A1sLog.Error("Day7", "Smoke FAIL: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры
      

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

Хронометраж (простая метрика времени)


Функция UnloadTimed(ТекстQ, П1 = Неопределено, П2 = Неопределено) Экспорт
    Старт = ТекущаяДата();
    Таб = A1sQ.Unload(ТекстQ, П1, П2);
    Сек = РазностьДат(ТекущаяДата(), Старт, ВидРазницыДат.ВСекундах);
    A1sLog.Info("Day7", "Unload: строк=" + Таб.Количество() + ", сек=" + Сек);
    Возврат Таб;
КонецФункции

Функция ExecuteQTimed(ТекстQ, П1 = Неопределено, П2 = Неопределено) Экспорт
    Старт = ТекущаяДата();
    Рез = A1sQ.ExecuteQ(ТекстQ, П1, П2);
    Сек = РазностьДат(ТекущаяДата(), Старт, ВидРазницыДат.ВСекундах);
    A1sLog.Info("Day7", "ExecuteQ: сек=" + Сек);
    Возврат Рез;
КонецФункции
      

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

Минимизируйте колонки и строки

Было: лишние поля и без лимита


ТекстQ = "
|ВЫБРАТЬ
|    *
|ИЗ Справочник.Номенклатура КАК Ном
";
Таб = A1sQ.Unload(ТекстQ); // дорого, приносит всё
      

Стало: минимум полей + лимит


ТекстQ = "
|ВЫБРАТЬ ПЕРВЫЕ &Лимит
|    Ном.Ссылка       КАК ID,
|    Ном.Наименование КАК Name
|ИЗ Справочник.Номенклатура КАК Ном
|УПОРЯДОЧИТЬ ПО Name
";
Таб = A1sQ.Unload(ТекстQ, 20);
Имена = Таб.ВыгрузитьКолонку("Name");
      

COUNT и EXISTS вместо «принести всё»

COUNT


ТекстQ = "
|ВЫБРАТЬ
|    COUNT(Ном.Ссылка) КАК Cnt
|ИЗ Справочник.Номенклатура КАК Ном
|ГДЕ Ном.ЭтоГруппа = &ТолькоГруппы
";
Рез = A1sQ.ExecuteQ(ТекстQ, Ложь);
Вб  = Рез.Выбрать();
Cnt = 0; Если Вб.Следующий() Тогда Cnt = Вб.Cnt; КонецЕсли;
A1sLog.Info("Day7", "Позиции (не группы): " + Cnt);
      

EXISTS (через «ПЕРВЫЕ 1»)


ТекстQ = "
|ВЫБРАТЬ ПЕРВЫЕ 1
|    1 КАК One
|ИЗ Справочник.Номенклатура КАК Ном
|ГДЕ Ном.Наименование = &Имя
";
Есть = A1sO.NotEmpty(ExecuteQFirstValue(ТекстQ, "Кабель ПВС"));
A1sLog.Info("Day7", "Существует точное имя: " + A1sS.AsString(Есть));
      

Смотри также готовые QT-шаблоны на Дне 6.

Поиск по маске: избегайте «%строка%»

Было: любой фрагмент


ТекстQ = "
|ВЫБРАТЬ ПЕРВЫЕ &Лимит
|    Ном.Ссылка, Ном.Наименование
|ИЗ Справочник.Номенклатура КАК Ном
|ГДЕ Ном.Наименование ПОДОБНО &Маска
";
Таб = A1sQ.Unload(ТекстQ, 50, "%кабель%");
      

Стало: начинается с


ТекстQ = "
|ВЫБРАТЬ ПЕРВЫЕ &Лимит
|    Ном.Ссылка, Ном.Наименование
|ИЗ Справочник.Номенклатура КАК Ном
|ГДЕ Ном.Наименование НАЧИНАЕТСЯ С &Префикс
|УПОРЯДОЧИТЬ ПО Ном.Наименование
";
Таб = A1sQ.Unload(ТекстQ, 50, "Кабель");
      

Пагинация без OFFSET: keyset-подход

Храним «последнюю пару» (LastName, LastID) и запрашиваем дальше по ключу, а не по смещению.


Функция НомПостранично(Лимит, LastName = "", LastID = Неопределено) Экспорт
    Осн = "
    |ВЫБРАТЬ ПЕРВЫЕ &Лимит
    |    Ном.Наименование КАК Name,
    |    Ном.Ссылка       КАК ID
    |ИЗ Справочник.Номенклатура КАК Ном
    ";

    Если A1sO.NotEmpty(LastName) Тогда
        Осн = Осн + "
        |ГДЕ (Ном.Наименование > &LastName)
        |   ИЛИ (Ном.Наименование = &LastName И Ном.Ссылка > &LastID)
        ";
        Осн = Осн + "
        |УПОРЯДОЧИТЬ ПО Name, ID
        ";
        Возврат A1sQ.Unload(Осн, Лимит, LastName, LastID);
    Иначе
        Осн = Осн + "
        |УПОРЯДОЧИТЬ ПО Name, ID
        ";
        Возврат A1sQ.Unload(Осн, Лимит);
    КонецЕсли;
КонецФункции
      

Keyset стабилен: не «перескакивает» строки при одновременных изменениях данных.

Чек-лист оптимизаций

Практика (15–30 минут)

  1. Обверните ваш «тяжёлый» запрос в SmokeQ и UnloadTimed — зафиксируйте секунды и объём.
  2. Сократите колонки до необходимых; добавьте ПЕРВЫЕ &Лимит — сравните время.
  3. Замените «%маска%» на «НАЧИНАЕТСЯ С» там, где применимо.
  4. Сделайте страницу списка с keyset-пагинацией (по Name, ID).
  5. Все результаты логируйте через A1sLog — получите объективные цифры.

Что дальше

День 8: Поиск и выбор данных — практические приёмы фильтрации и выборок для UI/отчётов.