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

A1sQ.ValueQ

Назначение: вернуть скаляр из первой строки и первого столбца результата запроса.
Поведение: при пустом результате/ошибке вернёт DefaultValue (по умолчанию — Неопределено).
Где применять: агрегаты, простые поля, быстрые проверки параметров/настроек.
Ключевая мысль: ValueQ выгружает результат целиком через Unload и читает первую ячейку. Для больших наборов — ограничивайте запрос ПЕРВЫЕ 1 и задавайте сортировку. скалярдефолтпросто

Сигнатура

Function ValueQ(
    QueryText,
    DefaultValue = Undefined,
    Value1 = Undefined, Value2 = Undefined, Value3 = Undefined, Value4 = Undefined,
    Value5 = Undefined, Value6 = Undefined, Value7 = Undefined, Value8 = Undefined
) Export

Параметры

  • QueryText — текст запроса 1С (SELECT).
  • DefaultValue — значение по умолчанию при пустом результате/ошибке.
  • Value1..Value8 — позиционные значения для &Парам по порядку появления.

Возвращаемое значение

Любой скаляр совместимого типа: число, строка, дата, булево, ссылка и т.п. — первый столбец первой строки. Иначе — DefaultValue.

Как работает (пошагово)

Function ValueQ(QueryText, DefaultValue = Undefined,
                Value1 = Undefined, Value2 = Undefined, Value3 = Undefined, Value4 = Undefined,
                Value5 = Undefined, Value6 = Undefined, Value7 = Undefined, Value8 = Undefined) Export

    Try
        // 1) Выполняем и выгружаем результат в ТаблицаЗначений
        VT = Unload(QueryText, Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8);

        // 2) Проверяем наличие хотя бы 1 строки и 1 колонки
        If VT.Количество() > 0 And VT.Колонки.Количество() > 0 Then
            Return VT[0][0]; // 3) Берем первую ячейку
        EndIf;

    Except
        // 4) Логируем и возвращаем дефолт
        A1sS.Print("ValueQ error: " + ErrorDescription());
    EndTry;

    Return DefaultValue;
EndFunction
Важно: DefaultValue используется только при пустом результате/ошибке. Если первая ячейка равна NULL/Неопределено, вернётся именно это значение. Для коалесса используйте ЕСТЬNULL(Поле, &Деф) в запросе.

Примеры

1) Одно поле из одной строки

// Имя пользователя или "Не найден"
Имя = A1sQ.ValueQ(
    "ВЫБРАТЬ Наименование ИЗ Справочник.Пользователи ГДЕ Ссылка = &U",
    "Не найден",
    Пользователь
);

2) Агрегат

КолВо = A1sQ.ValueQ(
    "ВЫБРАТЬ COUNT(*) КАК C ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= &D",
    0,
    НачалоПериода
);

3) Коалесс к дефолту на стороне СУБД

Цена = A1sQ.ValueQ(
    "ВЫБРАТЬ ЕСТЬNULL(Цена, &Деф) КАК V ИЗ РегистрСведений.Цены
     ГДЕ Номенклатура = &Ном И Дата <= &D
     УПОРЯДОЧИТЬ ПО Дата УБЫВ ПЕРВЫЕ 1",
    0, // дефолт при пустом результате/ошибке
    0, Номенклатура, ДатаНа
);

Сравнение: до / после

Без ValueQС ValueQ
Попытка
    VT = A1sQ.Unload("ВЫБРАТЬ Наименование ИЗ ... ГДЕ Ссылка = &U", Пользователь);
    Если VT.Количество() > 0 И VT.Колонки.Количество() > 0 Тогда
        Имя = VT[0][0];
    Иначе
        Имя = "Не найден";
    КонецЕсли;
Исключение
    A1sS.Print(ОписаниеОшибки());
    Имя = "Ошибка";
КонецПопытки;
Имя = A1sQ.ValueQ(
    "ВЫБРАТЬ Наименование ИЗ ... ГДЕ Ссылка = &U",
    "Не найден",
    Пользователь
);

Про производительность

  • Unload выгружает весь набор в память. Для небольших результатов это ок.
  • Ограничивайте: добавляйте ПЕРВЫЕ 1 и нужную УПОРЯДОЧИТЬ ПО.
  • Если набор потенциально большой — см. быстрый потоковый вариант ниже.

Альтернатива: потоковый ValueQFast

// Быстрее и без полной выгрузки (рекомендуйте ПЕРВЫЕ 1 в запросе)
Функция ValueQFast(QueryText, DefaultValue = Неопределено,
                   Value1 = Неопределено, Value2 = Неопределено, Value3 = Неопределено,
                   Value4 = Неопределено, Value5 = Неопределено, Value6 = Неопределено,
                   Value7 = Неопределено, Value8 = Неопределено) Экспорт
    Попытка
        S = ExecuteQ(QueryText, Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8);
        Если S.Следующий() Тогда
            Возврат S[0]; // первое поле текущей строки
        КонецЕсли;
    Исключение
        A1sS.Print("ValueQFast error: " + ОписаниеОшибки());
    КонецПопытки;
    Возврат DefaultValue;
КонецФункции

Типичные ошибки

❌ Перепутан порядок параметров
ValueQ("... ГДЕ Поле1 = &P1 И Поле2 = &P2", Деф, Знач2, Знач1);

// ✅ Правильно
ValueQ("... ГДЕ Поле1 = &P1 И Поле2 = &P2", Деф, Знач1, Знач2);

❌ Ожидание, что DefaultValue вернется при NULL в первой ячейке
// Функция вернет фактическое NULL/Неопределено.
// Для коалесса используйте ЕСТЬNULL(Поле, &Деф) в запросе.

❌ Нет сортировки, но нужна «первая по смыслу» запись
// Добавляйте УПОРЯДОЧИТЬ ПО ... и ПЕРВЫЕ 1.

Мини‑чеклист

  • Первый столбец — именно то поле, которое нужно?
  • Нужна сортировка/ограничение ПЕРВЫЕ 1?
  • DefaultValue согласован по типу с ожидаемым значением?
  • Параметры переданы в правильном порядке?

FAQ

Почему возвращается именно первая ячейка?
ValueQ ориентирован на «скаляр из запроса». Это минимальный и предсказуемый контракт.
Как вернуть дефолт при NULL в самой ячейке?
Используйте ЕСТЬNULL(Поле, &Деф) (или IFNULL‑аналог) в самом запросе и передайте &Деф отдельным параметром.
Можно ли использовать с A1sQ.QT?
Да. Соберите текст через QT и передайте в ValueQ.
  • A1sQ.FirstRowQ — вернуть всю первую строку.
  • A1sQ.ExistsQ — булев ответ «есть/нет».
  • A1sQ.ExecuteQ — потоковая выборка для обхода множества.
  • A1sQ.Unload — выгрузка результата в ТаблицаЗначений.