A1sQ.FirstRowQ
Назначение: получить первую строку результата запроса одной функцией.
Проблема: стандартно нужны 3–4 строчки кода с проверками и обработкой ошибок.
Решение: FirstRowQ выполняет запрос, делает Следующий(), и возвращает уже позиционированную выборку или Неопределено.
Проблема: стандартно нужны 3–4 строчки кода с проверками и обработкой ошибок.
Решение: FirstRowQ выполняет запрос, делает Следующий(), и возвращает уже позиционированную выборку или Неопределено.
Идеально для: быстрого чтения «шапки» документа, проверки дублей, получения «последнего/первого» элемента, компактной валидации. минимум кодабезопасночитабельно
Сигнатура
Function FirstRowQ(
QueryText,
Value1 = Undefined, Value2 = Undefined, Value3 = Undefined, Value4 = Undefined,
Value5 = Undefined, Value6 = Undefined, Value7 = Undefined, Value8 = Undefined,
TempTablesManager = Undefined
) Export
Параметры
- QueryText — текст запроса 1С (или генератор через A1sQ.QT).
- Value1..Value8 — позиционные значения для параметров &Парам по порядку появления.
- TempTablesManager — менеджер временных таблиц (опционально).
Возвращаемое значение
ВыборкаИзРезультатаЗапроса, уже позиционированная на первой записи; либо Неопределено, если записей нет/возникла ошибка.
Пошаговая логика
Функция FirstRowQ(QueryText, Value1 = Неопределено, Value2 = Неопределено, Value3 = Неопределено,
Value4 = Неопределено, Value5 = Неопределено, Value6 = Неопределено,
Value7 = Неопределено, Value8 = Неопределено, TempTablesManager = Неопределено) Экспорт
Попытка // 1) Защищенное выполнение
// 2) Выполняем запрос через общий конвейер ExecuteQ()
Выборка = ExecuteQ(QueryText, Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, TempTablesManager);
// 3) Проверяем наличие данных (позиционируемся на первой записи)
Если Выборка.Следующий() Тогда
Возврат Выборка; // уже стоит на первой строке
КонецЕсли;
Исключение
// 4) Любая ошибка логируется и функция возвращает Неопределено
A1sS.Print("FirstRowQ error: " + ОписаниеОшибки());
КонецПопытки;
Возврат Неопределено;
КонецФункции
Примеры
1) Пользователь по УИД
УИД = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
Row = A1sQ.FirstRowQ("
|ВЫБРАТЬ Ссылка, Наименование, Заблокирован
|ИЗ Справочник.Пользователи
|ГДЕ ИдентификаторПользователяИБ = &UID", УИД);
Если Row <> Неопределено Тогда
Если Row.Заблокирован Тогда ВызватьИсключение("Пользователь заблокирован!"); КонецЕсли;
Сообщить("Найден: " + Row.Наименование);
Иначе
ВызватьИсключение("Пользователь не найден!");
КонецЕсли;
2) Информация об организации
Org = A1sQ.FirstRowQ("
|ВЫБРАТЬ Наименование, ИНН, ЮридическийАдрес
|ИЗ Справочник.Организации
|ГДЕ Ссылка = &Орг", ТекущаяОрганизация);
Заголовок = (Org <> Неопределено) ?
("Организация: " + Org.Наименование + " (ИНН: " + Org.ИНН + ")") :
"Организация не определена";
3) Последний документ (по дате/номеру)
Last = A1sQ.FirstRowQ("
|ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка, Дата, Номер, Сумма
|ИЗ Документ.ПоступлениеТоваровУслуг
|ГДЕ Организация = &Орг
|УПОРЯДОЧИТЬ ПО Дата УБЫВ, Номер УБЫВ", ТекущаяОрганизация);
Если Last <> Неопределено Тогда
Сообщить("Последнее поступление: №" + Last.Номер
+ " от " + Формат(Last.Дата, "ДФ=dd.MM.yyyy")
+ " на сумму " + Строка(Last.Сумма));
Иначе
Сообщить("Документы поступления не найдены");
КонецЕсли;
4) Проверка дублей
Дубль = A1sQ.FirstRowQ("
|ВЫБРАТЬ Ссылка, Наименование
|ИЗ Справочник.Номенклатура
|ГДЕ Артикул = &Артикул И Ссылка <> &Ссылка",
НоваяНоменклатура.Артикул, НоваяНоменклатура.Ссылка);
Если Дубль <> Неопределено Тогда
ВызватьИсключение("Артикул уже используется: " + Дубль.Наименование);
КонецЕсли;
Сравнение: до / после
| Без FirstRowQ | С FirstRowQ |
|---|---|
|
|
Паттерны использования
- «Прочитай и реши»: быстро решаем, продолжать ли обработку, не гоняя весь набор.
- «Дай шапку»: тянем только ключевые поля первой строки для заголовков форм и сообщений.
- «Антидубли»: один вызов — одна валидация перед записью.
Особенности и нюансы
✅ Возвращает выборку, УЖЕ позиционированную на первой записи
• Сразу обращайтесь к полям: Row.Поле1, Row.Поле2
• НЕ вызывайте Row.Следующий() повторно — иначе уйдете на вторую запись
✅ Автоматическая обработка ошибок
• Исключения не «падают» наружу — печатаются через A1sS.Print()
• Возвращаемое значение всегда определено (Выборка или Неопределено)
✅ Поддержка до 8 параметров
• Передаются позиционно в порядке появления &Param в тексте запроса
❌ Ограничения
• Только первая строка. Для обхода множества — используйте ExecuteQ/Unload
⚠️ Тонкости
• Выборка привязана к результату запроса — не храните ее «надолго»
• Для «последнего» объекта лучше задайте сортировку и ПЕРВЫЕ 1 в запросе
Сравнение с другими функциями A1sQ
// FirstRowQ — когда нужна вся первая строка
Row = A1sQ.FirstRowQ("ВЫБРАТЬ Ссылка, Наименование ИЗ ... ГДЕ ...", Парам);
// ValueQ — когда нужно одно значение/по умолчанию
Имя = A1sQ.ValueQ("ВЫБРАТЬ Наименование ИЗ ... ГДЕ ...", "Не найдено", Парам);
// ExistsQ — когда нужна быстрая проверка существования
Если A1sQ.ExistsQ("ВЫБРАТЬ * ИЗ ... ГДЕ ...", Парам) Тогда ... КонецЕсли;
// ExecuteQ — когда нужно обойти набор строк
S = A1sQ.ExecuteQ("ВЫБРАТЬ ... ИЗ ... ГДЕ ...", Парам);
Пока S.Следующий() Цикл
// обработка
КонецЦикла;
// Unload — когда нужна таблица значений целиком
ТЗ = A1sQ.Unload("ВЫБРАТЬ ... ИЗ ... ГДЕ ...", Парам);
Типичные ошибки
❌ Повторный вызов Следующий()
Row = A1sQ.FirstRowQ("ВЫБРАТЬ * ИЗ Справочник.Пользователи");
Если Row <> Неопределено Тогда
// НЕПРАВИЛЬНО:
Если Row.Следующий() Тогда ... // уйдете на вторую запись!
КонецЕсли;
// ✅ Правильно
Row = A1sQ.FirstRowQ("ВЫБРАТЬ * ИЗ Справочник.Пользователи");
Если Row <> Неопределено Тогда
Имя = Row.Наименование;
КонецЕсли;
❌ Без проверки на Неопределено
Row = A1sQ.FirstRowQ("ВЫБРАТЬ * ИЗ НесуществующаяТаблица");
Имя = Row.Наименование; // ошибка
// ✅ Правильно
Row = A1sQ.FirstRowQ("ВЫБРАТЬ * ИЗ Справочник.Пользователи");
Имя = (Row <> Неопределено) ? Row.Наименование : "Не найдено";
❌ Перепутанный порядок параметров
Row = A1sQ.FirstRowQ("... ГДЕ Поле1 = &P1 И Поле2 = &P2", Знач2, Знач1);
// ^ порядок нарушен!
// ✅ Правильно
Row = A1sQ.FirstRowQ("... ГДЕ Поле1 = &P1 И Поле2 = &P2", Знач1, Знач2);
FAQ
Почему функция возвращает выборку, а не структуру?
Так мы избегаем копирования и дополнительных аллокаций. Вы читаете поля напрямую из курсора.
Можно ли использовать c A1sQ.QT и A1sQ.ExecuteQ?
Да. Передайте текст, собранный через QT, или используйте полноформатный запрос — FirstRowQ сам вызывает ExecuteQ.
Что будет при ошибке синтаксиса?
Ошибка будет залогирована через A1sS.Print, а функция вернет Неопределено.
Связанные функции
- A1sQ.ExistsQ — логический ответ «есть/нет».
- A1sQ.ValueQ — первое значение с дефолтом.
- A1sQ.ExecuteQ — выборка для обхода множества строк.