Как в запросе обратиться к реквизитам табличных частей

Нужно вывести данные табличной части документа в отчёт. В табличном документе может быть несколько строк (например пускай будет больше одной, т.е две)
соответственно мне эти две строки и нужно вывести в отчёт. Сама процедура счас выглядит так.

ТабДок   = новый ТабличныйДокумент;
   табДок.Очистить();

      Запрос = Новый запрос;
   Запрос.Текст = «ВЫБРАТЬ
                  |   Приемка_СИ.Контрагент.Полное_наименование,
                  |   Приемка_СИ.Контрагент.ИНН,
                  |   Приемка_СИ.Дата,
                  |   Приемка_СИ.Номер,
               |    Приемка_СИ.ССылка,

                  |   Приемка_СИ.Приборы.(
                  |      Заводской_Номер,
                  |      Тип_СИ.Наименование,
                  |      Марка.Наименование,
                  |      ДУ.Наименование,
                  |      Год_выпуска,
                  |      Паспорт,
                  |      Предыдущее_свидетельство
                  |   )
                  |ИЗ
                  |   Документ.Приемка_СИ КАК Приемка_СИ»;               

                                                ВыборкаДанные = Запрос.Выполнить().Выбрать();

       // получаем макет
   Макет = ПолучитьМакет («Макет_акт»);

   ОбластьШапка = макет.ПолучитьОбласть(«Шапка»);

      ОбластьЗаголовок = макет.ПолучитьОбласть(«Заголовок»);

      ОбластьДанные  = Макет.получитьОбласть («Данные»);

      ОбластьПодвал  = Макет.получитьОбласть («Подвал»);

       Пока ВыборкаДанные.следующий() Цикл

         ОбластьШапка.Параметры.номер_акт = «№»+ номер+» «+ «от» + » » +Формат(Дата,»ДФ=»»дд.ММ.гггг»»»);

    Для каждого СтрокаТЧ ИЗ ВыборкаДанные.Ссылка.Приборы Цикл
        ОбластьДанные.Параметры.ЗавНомер_акт = СтрокаТЧ.Заводской_Номер;
    КонецЦикла;

      КонецЦикла;

      //ТабДок.вывести(ОбластьДанные);
    ТабДок.вывести(ОбластьШапка );
    ТабДок.вывести(ОбластьЗаголовок);
    ТабДок.Вывести(ОбластьДанные);

    ТабДок.Вывести(ОбластьПодвал);

    ТабДок.показать();

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

Есть такой запрос

 Запрос.Текст =    

        «ВЫБРАТЬ

        |    Контрагенты.Наименование,

        |    Контрагенты.ПолнНаименование,

        |    Контрагенты.ИНН,

        |    Контрагенты.ЮрАдрес,

        |    Контрагенты.КПП,

        |    Контрагенты.Город,

        |    Контрагенты.ВидКонтрагента,

        |    Контрагенты.ОсновнойДоговор,

        |    Контрагенты.ОсновнойСчет,

        |    Контрагенты.Комментарий,

        |    Контрагенты.Поставщик,

        |    Контрагенты.Покупатель,

        |    Контрагенты.РеквизитыРегистрацииИП,

        |    Контрагенты.Представление,

        |    Контрагенты.Связи.(

        |        Контрагент КАК Контрагент1

        |    ),

        |    Контрагенты.Адреса.(

        |        Город КАК Город1,

        |        Адрес КАК Адрес1

        |    )

        |ИЗ

        |    Справочник.Контрагенты КАК Контрагенты

        |ГДЕ

        |    Контрагенты.ИНН <> «»»»»;    

как к простым реквизитам обратиться я знаю, а как к тем, что из табличной части?

То есть я потом пишу

Результат = Запрос.Выполнить();              

   ВыборкаСсылка = Результат.Выбрать();    

     
   
       
            Пока ВыборкаСсылка.Следующий() Цикл

   ОбластьСтрока.Параметры.р7=ВыборкаСсылка.Адреса.Город1;

ОбластьСтрока.Параметры.р8=ВыборкаСсылка.Адреса.Адрес1;

ОбластьСтрока.Параметры.р9=ВыборкаСсылка.Связи.Контрагент1;

а программа говорит что нет такого «город1».

Обращение к табличной части как вложенной таблице

В этом случае поле результата запроса будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе табличной части.

// получение табличной части как вложенной таблицы

// результата запроса

ВЫБРАТЬ Номер, Дата, Товары

ИЗ Документ.АвансовыйОтчет

// получение нескольких колонок табличной части

// как вложенной таблицы

ВЫБРАТЬ Номер, Дата, Товары.(Номенклатура, Количество)

ИЗ Документ.АвансовыйОтчет

Обратите внимание, что если выполнить следующий запрос, то в результате запроса будет две вложенные таблицы: в первой — одна колонка Номенклатура, а во второй — колонка Количество:

ВЫБРАТЬ Номер, Дата, Товары.Номенклатура, Товары.Количество

ИЗ Документ.АвансовыйОтчет

Обращение к табличной части как таблице-источнику

При таком способе обращения имя вложенной таблицы фигурирует в имени таблицы-источника (предложение ИЗ или полные имена полей) и в результате запроса нет вложенных таблиц.

//выборка всех полей из табличной части

ВЫБРАТЬ * ИЗ Документ.АвансовыйОтчет.Товары

// выборка определенных полей из табличной части

ВЫБРАТЬ Номенклатура, Количество, Цена, Сумма

ИЗ Документ.АвансовыйОтчет.Товары

// задание псевдонимов для полей табличной части

ВЫБРАТЬ Документ.АвансовыйОтчет.Товары.(Номенклатура, Сумма КАК СуммаПоСтроке)

// обращение к реквизитам документа и реквизитам

// табличной части (поле Ссылка)

ВЫБРАТЬ

// реквизиты документа

Ссылка.Номер,

Ссылка.Дата,

Ссылка.Ответственный,

//реквизиты табличной части

Номенклатура,

Количество,

Цена,

Сумма

ИЗ Документ.АвансовыйОтчет.Товары

Строки табличной части любого документа в 1С 8 можно получить при помощи запроса, для того что бы в результат запроса попали данные только одного (нужного нам) документа следует в разделе запроса ГДЕ наложить условие на поле Ссылка. Запрос к табличной части — один из самых простых способов получить данные, например для печатной формы.

1с запрос к табличной части. Пример написания

Рассмотрим запрос к табличной части Продукция документа Отчет производства за смену, пусть в переменной СсылкаНаДокумент содержится ссылка на документ табличную часть которого нам необходимо получить.

Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Документ", СсылкаНаДокумент);

Запрос.Текст = 
"ВЫБРАТЬ
|    Продукция.Ссылка,
|    Продукция.НомерСтроки,
|    Продукция.ЕдиницаИзмерения,
|    Продукция.Количество,
|    Продукция.КоличествоМест,
|    Продукция.Коэффициент,
|    Продукция.Номенклатура,
|    Продукция.НоменклатурнаяГруппа,
|    Продукция.Счет,
|    Продукция.СчетЗатрат,
|    Продукция.ПлановаяСтоимость,
|    Продукция.СуммаПлановая,
|    Продукция.Спецификация
|ИЗ
|    Документ.ОтчетПроизводстваЗаСмену.Продукция КАК Продукция 
|ГДЕ
|    ОтчетПроизводстваЗаСменуПродукция.Ссылка = &Документ";

В поля запроса необязательно перемещать все имеющиеся реквизиты таб. части документа, можно использовать только необходимые вам.

Пример2:

Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Документ", СсылкаНаДокумент);

Запрос.Текст = 
"ВЫБРАТЬ
|    Продукция.Количество,
|    Продукция.Номенклатура
|ИЗ
|    Документ.ОтчетПроизводстваЗаСмену.Продукция КАК Продукция
|ГДЕ
|    Продукция.Ссылка = &Документ";

Если вы не умеете писать запросы на встроенном языке 1с, можете прочитать статью Язык запросов 1с — оператор Выбрать, в ней подробно описывается из каких частей состоит запрос в 1С 8 и как он правильно пишется. Следующим этапом прочтите ее вторую часть Запросы 1с 8 — Программная работа. Изучение языка запросов поможет вам стать профессиональным программистом 1с.


  Как получить доступ к реквизитам объекта?

Статья носит справочный характер. Предназначена для начинающих программистов.

Получить массив реквизитов объекта можно при помощи самого объекта:

                ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
                ДокОбъект = ДокСсылка.ПолучитьОбъект();
                МассивРеквизитовОбъекта = ДокОбъект.Метаданные().Реквизиты;

  Получив массив реквизитов, можно организовать Цикл для просмотра имен реквизитов:

 Для каждого Реквизит Из ДокОбъект.Метаданные().Реквизиты Цикл
                        Сообщить(Реквизит.Имя + " :" + Реквизит.Представление());
КонецЦикла;

Для того, чтобы получить значения реквизитов объекта вообще говоря надо обратиться с запросом к БД, типа:

 
Запрос = "ВЫБРАТЬ
                |       ИмяРеквизита,
                |ИЗ
                |       Объект.ТипОбъекта КАК ОбъектТипОбъекта
                |ГДЕ
                |       ОбъектТипОбъекта.Ссылка = &СсылкаНаОбъект
Запрос.УстановитьПараметр("СсылкаНаОбъект", СсылкаНаОбъект);

В запрос надо передать ссылку на объект и имя реквизита. Запрос вернет таблицу или выборку со значением реквизита.

Удобнее конечно для поиска значений реквизитов воспользоваться готовыми решениями, например фунцией ПолучитьЗначенияРеквизитов() общего модуля ОбщегоНазначения.

 
// Возвращает структуру, содержащую значения реквизитов прочитанные из информационной базы
// по ссылке на объект.
//
//  Если доступа к одному из реквизитов нет, возникнет исключение прав доступа.
//  Если необходимо зачитать реквизит независимо от прав текущего пользователя,
//  то следует использовать предварительный переход в привилегированный режим.
//
// Параметры:
//  Ссылка       - ссылка на объект, - элемент справочника, документ, ...
//  ИменаРеквизитов - Строка или Структура - Если Строка, то имена реквизитов,
//               перечисленные через запятую, в формате требований к свойствам структуры.
//               Например, "Код, Наименование, Родитель".
//               Если Структура, то в качестве ключа передается псевдоним поля для
//               возвращаемой структуры с результатом, а в качестве значения (опционально)
//               - фактическое имя поля в таблице.
//               Если значение не определено, то имя поля берется из ключа.
//
// Возвращаемое значение:
//  Структура    - содержит список свойств, как список имен в строке
//                 ИменаРеквизитов, со значениям реквизитов, прочитанных
//                 из информационной базы.
//
Функция ПолучитьЗначенияРеквизитов(Ссылка, ИменаРеквизитов) Экспорт
        Если ТипЗнч(ИменаРеквизитов) = Тип("Структура") Тогда
                СтруктураРеквизитов = ИменаРеквизитов;
        ИначеЕсли ТипЗнч(ИменаРеквизитов) = Тип("Строка") Тогда
                СтруктураРеквизитов = Новый Структура(ИменаРеквизитов);;
        Иначе
                ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                        НСтр("ru = 'Неверный тип второго параметра ИменаИлиСтруктураРеквизитов: %1'"),
                        Строка(ТипЗнч(ИменаРеквизитов)));
        КонецЕсли;
        ТекстПолей = "";
        Для каждого КлючИЗначение Из СтруктураРеквизитов Цикл
                ИмяПоля   = ?(ЗначениеЗаполнено(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Ключ));
                Псевдоним = СокрЛП(КлючИЗначение.Ключ);
                ТекстПолей  = ТекстПолей + ?(ПустаяСтрока(ТекстПолей), "", ",") + "
                        |       " + ИмяПоля + " КАК " + Псевдоним;
        КонецЦикла;
        Запрос = Новый Запрос(
                "ВЫБРАТЬ
                |" + ТекстПолей + "
                |ИЗ
                |       " + Ссылка.Метаданные().ПолноеИмя() + " КАК ПсевдонимЗаданнойТаблицы
                |ГДЕ
                |       ПсевдонимЗаданнойТаблицы.Ссылка = &Ссылка
                |");
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
        Выборка = Запрос.Выполнить().Выбрать();
        Выборка.Следующий();
        Результат = Новый Структура;
        Для каждого КлючИЗначение Из СтруктураРеквизитов Цикл
                Результат.Вставить(КлючИЗначение.Ключ);
        КонецЦикла;
        ЗаполнитьЗначенияСвойств(Результат, Выборка);
        Возврат Результат;
КонецФункции

Значение реквизитов в этой функции получено через запрос к БД. Возвращаемое значение — структура (ключ-значение). Пример использования:

         ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
        СтруктураНастроек = Новый Структура;
         //инициируем структуру настроек именами реквизитов
        Для каждого Реквизит Из ДокОбъект.Метаданные().Реквизиты Цикл
                СтруктураНастроек.Вставить(Реквизит.Имя, Реквизит.Имя);
        КонецЦикла;      
                
        ЗначенияРеквизитов = ПолучитьЗначенияРеквизитов(ДокСсылка , СтруктураНастроек);
        СканПростойСтруктуры(ЗначенияРеквизитов); //вывести структуру для просмотра
 

Поскольку в функцию ПолучитьЗначенияРеквизитов() во второй параметр надо передать структуру, то мы создали структуру и организовали Цикл ее инициализации данными из массива имен реквизитов объекта. Возвращает функция так же структуру (ключ-значение), с которой удобно работать. Для просмотра этой структуры можно воспользоваться циклом, либо вызвать функцию СканПростойСтруктуры(), которой передать структуру для просмотра.

 
Функция СканПростойСтруктуры(Структура)
        Для каждого Элемент из Структура Цикл
                Сообщить(Элемент.Ключ + ": " + Элемент.Значение);
        КонецЦикла;
КонецФункции

Если исследуемый объект использует так же еще и общие реквизиты, и их необходимо найти, то можно воспользоваться функцией МассивИменРеквизитовОбъекта(), которая находит не только реквизиты объекта но и общие и даже стандартные реквизиты, которые использует объект:

 
// Возвращает массив имен всех реквизитов переданного объекта
//
Функция МассивИменРеквизитовОбъекта(Объект) Экспорт
    МассивИменРеквизитов = Новый Массив;
    Если ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
        МетаданныеОбъекта = Объект;
    Иначе
        МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
        Если МетаданныеОбъекта = Неопределено Тогда
            Возврат МассивИменРеквизитов;
        КонецЕсли;
    КонецЕсли;
    Для индекс = 0 по 1 Цикл
//        КоллекцияРеквизитов = ?(индекс = 0, МетаданныеОбъекта.СтандартныеРеквизиты, МетаданныеОбъекта.Реквизиты);
        КоллекцияРеквизитов = МетаданныеОбъекта.Реквизиты;
        Для каждого Реквизит Из КоллекцияРеквизитов Цикл
            МассивИменРеквизитов.Добавить(Реквизит.Имя);
        КонецЦикла;
    КонецЦикла;
    Для каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
        Если ИспользуетсяОбщийРеквизит(ОбщийРеквизит, МетаданныеОбъекта) Тогда
            МассивИменРеквизитов.Добавить(ОбщийРеквизит.Имя);
        КонецЕсли;
    КонецЦикла;
    Возврат МассивИменРеквизитов;
КонецФункции

Тогда программа будет выглядеть так:

 
                ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
                ДокОбъект = ДокСсылка.ПолучитьОбъект();
                                
                мМассивИмен =  МассивИменРеквизитовОбъекта(ДокОбъект);
                СтруктураНастроек = Новый Структура;
                Для каждого эл Из мМассивИмен Цикл
                        СтруктураНастроек.Вставить(эл, эл);
                КонецЦикла;
                ЗначенияРеквизитов = ОбщегоНазначения.ПолучитьЗначенияРеквизитов(ДокСсылка , СтруктураНастроек);
                СканПростойСтруктуры(ЗначенияРеквизитов);

Вспомогательная функция:

 
// Проверяет используется ли в Объекте указанный общий реквизит
//
Функция ИспользуетсяОбщийРеквизит(ОбщийРеквизит, Объект) Экспорт
    Если ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
        МетаданныеОбъекта = Объект;
    Иначе
        МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
        Если МетаданныеОбъекта = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;
    Если ТипЗнч(ОбщийРеквизит) = Тип("ОбъектМетаданных") Тогда
        МетаданныеОбщегоРеквизита = ОбщийРеквизит;
    Иначе
        МетаданныеОбщегоРеквизита = Метаданные.ОбщиеРеквизиты.Найти(ОбщийРеквизит);
        Если МетаданныеОбщегоРеквизита = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;
    ЭлементСостава = МетаданныеОбщегоРеквизита.Состав.Найти(МетаданныеОбъекта);
    Если ЭлементСостава = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    пИспользованиеОбщегоРеквизита = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита;
    Если ЭлементСостава.Использование = пИспользованиеОбщегоРеквизита.Использовать Тогда
        Возврат Истина;
    ИначеЕсли ЭлементСостава.Использование = пИспользованиеОбщегоРеквизита.НеИспользовать Тогда
        Возврат Ложь;
    Иначе
        пАвтоИспользованиеОбщегоРеквизита = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита;
        Если МетаданныеОбщегоРеквизита.АвтоИспользование = пАвтоИспользованиеОбщегоРеквизита.Использовать Тогда
            Возврат Истина;
        Иначе
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;
КонецФункции

Как получить значение отдельного реквизита объекта?

Иногда необязательно получать значения всего массива реквизитов. Программист как правило знает имя реквизита, значение которого необходимо получить. К отдельному реквизиту объекта можно обратиться просто по его имени:

Поставщик = ДокОбъект.Метаданные().Реквизиты.Поставщик;

Получить значение этого реквизита можно так же через запрос, написанный специально для этого реквизита. Но можно воспользоваться все той же функцией ПолучитьЗначенияРеквизитов(). Цикл для настройки структуры в этом случае не нужен, так как нам надо найти значение всего одного элемента:

 
                ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
                ДокОбъект = ДокСсылка.ПолучитьОбъект();
                                
                Организация = Строка(ДокОбъект.Метаданные().Реквизиты.Организация);
                СтруктураНастроек = Новый Структура;
                СтруктураНастроек.Вставить(Организация, Организация);
 
                ЗначенияРеквизитов = ОбщегоНазначения.ПолучитьЗначенияРеквизитов(ДокСсылка , СтруктураНастроек);
                СканПростойСтруктуры(ЗначенияРеквизитов);

Обратите внимание что здесь реквизит который необходимо найти преобразовывается к типу Строка, потому, что в структуру настроек надо передать именно строку.

Как найти имена реквизитов в таб части объекта?

Функция определяет есть ли реквизит в таб части документа:

// Позволяет определить есть ли среди реквизитов табличной части документа
// реквизит с переданным именем.
//
// Параметры:
//  ИмяРеквизита - строковое имя искомого реквизита,
//  МетаданныеДокумента - объект описания метаданных документа, среди реквизитов которого производится поиск.
//  ИмяТабЧасти  - строковое имя табличной части документа, среди реквизитов которого производится поиск
//
// Возвращаемое значение:
//  Истина - нашли реквизит с таким именем, Ложь - не нашли.
//
 
Функция ЕстьРеквизитТабЧастиДокумента(ИмяРеквизита, МетаданныеДокумента, ИмяТабЧасти) Экспорт
    ТабЧасть = МетаданныеДокумента.ТабличныеЧасти.Найти(ИмяТабЧасти);
    Если ТабЧасть = Неопределено Тогда // Нет такой таб. части в документе
        Возврат Ложь;
    Иначе
        Возврат НЕ (ТабЧасть.Реквизиты.Найти(ИмяРеквизита) = Неопределено);
    КонецЕсли;
КонецФункции

Пример использования:

 

        ИмяРеквизита = "Номенклатура";
        МетаданныеДокумента = ДокОбъект.Метаданные();
        ИмяТабЧасти = "Товары";
        
         Если ЕстьРеквизитТабЧастиДокумента(ИмяРеквизита, МетаданныеДокумента, ИмяТабЧасти) Тогда
            Сообщить("Реквизит есть!");
         Иначе
            Сообщить("Реквизита нет");
         КонецЕсли;
 

Сообщить имя реквизитов таб части:

 
Для каждого Реквизит Из ДокОбъект.Метаданные().ТабличныеЧасти.Найти("Товары").Реквизиты Цикл
        Собщить(Реквизит.Имя);
КонецЦикла; 

Как найти значение всех реквизитов всех таб частей документа через запрос

Чтобы найти значения всех реквизитов всех табличных частей объекта через запрос воспользуемся функцией

ПолучитьЗначенияРеквизитовТабЧасти().

Функция ПолучитьЗначенияРеквизитовТабчасти(Ссылка, ИменаРеквизитов, ИмяТабЧасти) Экспорт
        
        ИмяТЧ = ИмяТабЧасти;
        ПолноеИмя = Ссылка.Метаданные().ПолноеИмя();
           
        Если ТипЗнч(ИменаРеквизитов) = Тип("Структура") Тогда
                СтруктураРеквизитов = ИменаРеквизитов;
        ИначеЕсли ТипЗнч(ИменаРеквизитов) = Тип("Строка") Тогда
                СтруктураРеквизитов = Новый Структура(ИменаРеквизитов);;
        Иначе
                ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                        НСтр("ru = 'Неверный тип второго параметра ИменаИлиСтруктураРеквизитов: %1'"), 
                        Строка(ТипЗнч(ИменаРеквизитов)));
        КонецЕсли;
        ТекстПолей = "";
        Для Каждого КлючИЗначение Из СтруктураРеквизитов Цикл
                ИмяПоля   = ?(ЗначениеЗаполнено(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Ключ));
                Псевдоним = СокрЛП(КлючИЗначение.Ключ);
                ТекстПолей  = ТекстПолей + ?(ПустаяСтрока(ТекстПолей), "", ",") + "
                        |       " + ИмяПоля + " КАК " + Псевдоним;
        КонецЦикла;
        Запрос = Новый Запрос(
                "ВЫБРАТЬ
                |" + ТекстПолей + "
                |ИЗ
                |       " + ПолноеИмя + "." + ИмяТЧ + " КАК ПсевдонимЗаданнойТаблицы
                |ГДЕ
                |       ПсевдонимЗаданнойТаблицы.Ссылка = &Ссылка
                |");
                                
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
        Результат = Запрос.Выполнить().Выгрузить();
                
        Возврат Результат;
КонецФункции

 Пример использования:

 
        ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
        ДокОбъект = ДокСсылка.ПолучитьОбъект();
                                
        
        МассивТабЧастей = Новый Массив;
        Для каждого ТабЧасть Из ДокОбъект.Метаданные().ТабличныеЧасти Цикл
                МассивТабЧастей.Добавить(ТабЧасть.Имя);                 
        КонецЦикла;                                             
                
        Для Каждого ТабЧасть Из МассивТабЧастей Цикл
                        
                СтруктураНастроек = Новый Структура;
                Для каждого Реквизит Из ДокОбъект.Метаданные().ТабличныеЧасти.Найти(ТабЧасть).Реквизиты Цикл
                        СтруктураНастроек.Вставить(Реквизит.Имя, Реквизит.Имя);
                КонецЦикла;                                             
                        
                Сообщить("Имя таб части: " + ТабЧасть);
                ТабЗнач = ПолучитьЗначенияРеквизитовТабЧасти(ДокСсылка , СтруктураНастроек, ТабЧасть);
                                
                ПоказатьТаблицу(ТабЗнач);
                                
        КонецЦикла;
 

Вспомогательная функция:

 
функция ПоказатьТаблицу(Табл)
        
        Сообщить("///Функция ПоказатьТаблицу///");
        
        Количество = Табл.Колонки.Количество();
        
        Для каждого Строка из Табл Цикл
                Для Индекс = 0 По Количество-1 Цикл 
                        Сообщить(СокрЛП(Индекс)+" "+СокрЛП(Табл.Колонки[Индекс].Имя)+ ": " + Строка[СокрЛП(Табл.Колонки[Индекс].Имя)]);
                КонецЦикла;
        КонецЦикла;
        Сообщить("///Конец Функция ПоказатьТаблицу///");
КонецФункции  

Результат для документа «Реализация товаров услуг»:

Имя таб части: Товары
///Функция ПоказатьТаблицу///
0 ЕдиницаИзмерения: шт
1 ЕдиницаИзмеренияМест:
2 Качество: Новый
3 Количество: 1
4 КоличествоМест: 0
5 Коэффициент: 1
6 Номенклатура: Вентилятор настольный
7 ПроцентСкидкиНаценки: 0
8 СерияНоменклатуры: Н-908, С-890 от 01.01.2003
9 СпособСписанияОстаткаТоваров: Со склада
10 СтавкаНДС: Без НДС
11 Сумма: 445,5
12 СуммаНДС: 0
13 ХарактеристикаНоменклатуры:
14 Цена: 450
15 Склад: Магазин «Бытовая техника»
16 ПроцентАвтоматическихСкидок: 1
17 УсловиеАвтоматическойСкидки: По виду дисконтных карт
18 ЗначениеУсловияАвтоматическойСкидки: Серебряная карта
19 КлючСтроки: 3
20 КлючСвязи: 0
21 ЗаказПокупателя: Заказ покупателя ТД000000001 от 08.06.2008 12:00:00
0 ЕдиницаИзмерения: шт
1 ЕдиницаИзмеренияМест:
2 Качество: Новый
3 Количество: 1
4 КоличествоМест: 0
5 Коэффициент: 1
6 Номенклатура: Набор вентиляторов
7 ПроцентСкидкиНаценки: 0
8 СерияНоменклатуры:
9 СпособСписанияОстаткаТоваров: Со склада
10 СтавкаНДС: Без НДС
11 Сумма: 1948,32
12 СуммаНДС: 0
13 ХарактеристикаНоменклатуры:
14 Цена: 1968
15 Склад: Магазин «Бытовая техника»
16 ПроцентАвтоматическихСкидок: 1
17 УсловиеАвтоматическойСкидки: По виду дисконтных карт
18 ЗначениеУсловияАвтоматическойСкидки: Серебряная карта
19 КлючСтроки: 4
20 КлючСвязи: 0
21 ЗаказПокупателя: Заказ покупателя ТД000000001 от 08.06.2008 12:00:00
///Конец Функция ПоказатьТаблицу///

Имя таб части: ВозвратнаяТара
///Функция ПоказатьТаблицу///
///Конец Функция ПоказатьТаблицу///

Имя таб части: Услуги
///Функция ПоказатьТаблицу///
///Конец Функция ПоказатьТаблицу///

Имя таб части: СоставНабора
///Функция ПоказатьТаблицу///
0 Номенклатура: Вентилятор BINATONE ALPINE 160вт, напольный ,
1 ХарактеристикаНоменклатуры:
2 СерияНоменклатуры: 01234/11020/7654321, БОЛГАРИЯ
3 Количество: 1
4 ЕдиницаИзмерения: шт
5 Склад: Магазин «Бытовая техника»
6 Качество: Новый
7 СпособСписанияОстаткаТоваров: Со склада
8 КлючСтроки: 4
9 Цена: 1068
10 КлючСвязи: 0
0 Номенклатура: Вентилятор JIPONIC (Тайв.),
1 ХарактеристикаНоменклатуры:
2 СерияНоменклатуры: 11234/11020/7654321, ТАЙВАНЬ (КИТАЙ)
3 Количество: 1
4 ЕдиницаИзмерения: шт
5 Склад: Магазин «Бытовая техника»
6 Качество: Новый
7 СпособСписанияОстаткаТоваров: Со склада
8 КлючСтроки: 4
9 Цена: 900
10 КлючСвязи: 0
///Конец Функция ПоказатьТаблицу///

Имя таб части: СерийныеНомера

///Функция ПоказатьТаблицу///
///Конец Функция ПоказатьТаблицу///

Имя таб части: СерийныеНомераСоставНабора

///Функция ПоказатьТаблицу///
///Конец Функция ПоказатьТаблицу///

Имя таб части: ДокументыРасчетовСКонтрагентом

 ///Функция ПоказатьТаблицу///
///Конец Функция ПоказатьТаблицу///

Листинг 1.38. Отбор записей справочника «Клиенты» по условию

Нажмем кнопку Заполнить параметры и зададим значение параметра ШаблонТелефона как «_-___-___-__-__». Результат запроса (рис. 1.30) полностью совпадает с результатом при выполнении запроса, не использующего параметры в условии отбора

(см. рис. 1.28).

Рис. 1.30. Отбор записей справочника «Клиенты» по параметризированному условию

Как получить данные из табличной части некоторого документа

Часто может понадобиться вывести все данные из табличной части определенного документа или элемента справочника или другого объекта конфигурации, имеющего табличную часть.

Для этого в языке запросов существует удобная возможность – обращаться к табличной части как к отдельной таблице. При этом в тексте запроса можно использовать все ранее изученные нами конструкции: ВЫБРАТЬ, ИЗ и т. п. Синтаксис обращения к таблицеисточнику включает также имя табличной части – <Имя класса объектов>.<Имя объекта конфигурации>.<Имя табличной части>, например Документ.ЗаказТовара.Состав.

Следующий запрос выводит данные всех табличных частей из всех документов

ЗаказТовара (листинг 1.39).

Листинг 1.39. Вывод данных всех табличных частей из всех документов «ЗаказТовара»

В начале главы «Как хранятся данные в «1С:Предприятии»» мы рассматривали, как хранятся данные табличных частей в информационной базе «1С:Предприятия». Поля выборки запроса Товар, Количество, Сумма – это реквизиты табличной части документа, находящиеся в отдельной таблице базы данных, к которой мы обращаемся запросом. В этой таблице хранятся данные всех табличных частей документов определенного вида.

Результат выполнения запроса представлен на рис. 1.31.

Рис. 1.31. Вывод данных всех табличных частей из всех документов «ЗаказТовара»

Однако в таком виде мы не можем сказать, к какому клиенту и к какому заказу относится каждая из записей результата запроса. Для повышения информативности данных мы можем добавить в список полей выборки реквизиты документа Номер и Клиент.

Мы знаем, что поля Номер и Клиент хранятся в основной таблице документа, а поля Товар, Количество, Сумма из табличной части документа – в подчиненной таблице, связанной с основной таблицей по полю Ссылка.

Поскольку в нашем примере источником запроса является подчиненная таблица документа Документ.ЗаказТовара.Состав, то, чтобы получить данные из основной таблицы документа, нужно обращаться к полям таблицы через точку от поля табличной части Ссылка (листинг 1.40).

Листинг 1.40. Вывод данных из основной и подчиненной таблицы документов «ЗаказТовара»

Результат выполнения запроса представлен на рис. 1.32.

Рис. 1.32. Вывод данных из основной и подчиненной таблицы документов «ЗаказТовара»

Конечно, когда данных много, обычно требуется отобрать информацию из определенного документа. Для этого нужно добавить в запрос параметризированное условие, содержащее параметр, имеющий тип ссылки на документ ЗаказТовара (листинг 1.41).

Листинг 1.41. Вывод данных из определенного документа

Нажмем кнопку Заполнить параметры, и параметр Документ будет добавлен в окно параметров консоли запросов. Причем консоль запросов из текста запроса автоматически определяет не только имя, но и тип параметра. В предыдущем примере (см. рис. 1.29) мы использовали в условии отбора параметр примитивного типа (Строка). В данном случае параметр запроса имеет ссылочный тип – ДокументСсылка.ЗаказТовара.

В результате выполнения запроса мы увидим только те записи, которые относятся к конкретному заказу товаров, указанному в параметре Документ (рис. 1.33).

Рис. 1.33. Вывод данных из определенного документа

На самом деле данные для этого запроса выбирались из двух взаимосвязанных таблиц (основной и подчиненной таблиц документа, связанных по полю Ссылка), но подробнее мы остановимся на этом позже.

подробнее

Раздел «Как получить данные из таблицы, на которую ссылается поле другой таблицы».

Как получить данные из табличной части документа в качестве вложенной таблицы

Информацию из табличной части документа можно получить также, не обращаясь к подчиненной таблице, сразу из основной таблицы документа. В этом случае поле результата запроса, содержащее данные из табличной части (например,

ЗаказТовара.Состав), будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе табличной части (листинг

1.42).

Листинг 1.42. Выбор данных из табличной части в качестве вложенной таблицы

Вложенный результат запроса к табличной части состоит из стандартных полей Ссылка, НомерСтроки и полей с именами, соответствующими именам реквизитов табличной части документа (рис. 1.34).

Рис. 1.34. Поля табличной части, выбираемые запросом

Можно указать конкретные поля табличной части, которые нужно выбрать запросом

(листинг 1.43).

Листинг 1.43. Выбор данных из табличной части в качестве вложенной таблицы

Важно понимать, что при выполнении первого запроса будет получена одна вложенная таблица Состав, содержащая поля Товар, Количество и Сумма. А при выполнении второго запроса будет получено две вложенных таблицы: таблица Состав, содержащая результат запроса, который включает единственное поле Товар, и таблица Состав1,

содержащая результат запроса, который включает единственное поле Сумма (рис. 1.35).

Рис. 1.35. Вывод данных из документов «ЗаказТовара» в консоли запросов

При выполнении этих запросов в консоли запросов вместо данных вложенной таблицы будет выведен текст ТаблицаЗначений. Это значит, что данные табличной части, выбранные в качестве вложенного результата запроса, могут быть обработаны только с помощью встроенного языка.

подробнее

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

Как получить записи иерархической таблицы и расположить их в порядке иерархии

Вэтом примере мы рассмотрим особенности получения данных из иерархического справочника.

Внашей демонстрационной конфигурации существует иерархический справочник Товары с типом иерархии Иерархия групп и элементов. Такой справочник состоит из групп и элементов. Группы – это элементы справочника, которые имеют (или могут иметь) подчиненные себе элементы или другие группы. В отличие от них, элементы не имеют (и не могут иметь) подчиненных себе записей.

Иерархия может быть многоуровневой, то есть внутри групп могут быть другие группы и элементы, не являющиеся группами (рис. 1.36).

Рис. 1.36. Структура иерархического справочника

У рассмотренного на рис. 1.36 иерархического справочника есть стандартные поля: поле Родитель (ссылка на родительские записи у дочерних записей) и поле ЭтоГруппа (ИСТИНА для записей, являющихся группой, и ЛОЖЬ для записей, не являющихся группой).

В нашей демонстрационной конфигурации справочник Товары имеет трехуровневую иерархию и выглядит следующим образом (рис. 1.37).

Рис. 1.37. Справочник «Товары» в режиме «1С:Предприятие»

Выберем поля Код, Наименование, Родитель, ЭтоГруппа из справочника Товары и

отсортируем их по наименованию уже знакомым нам запросом (листинг 1.44).

Листинг 1.44. Вывод записей иерархического справочника «Товары»

Результат выполнения запроса представлен на рис. 1.38.

Рис. 1.38. Вывод записей иерархического справочника «Товары»

Мы видим, что записи справочника отсортированы по наименованию, но элементы групп (Обувь, Детская обувь, Продукты) идут вперемешку. Поскольку справочник является иерархическим, гораздо привычнее видеть записи этого справочника расположенными в иерархическом порядке. По умолчанию так и сделано в «1С:Предприятии».

Для этого изменим текст запроса. В предложении УПОРЯДОЧИТЬ ПО после имени поля Наименование напишем ключевое слово ИЕРАРХИЯ (листинг 1.45).

Листинг 1.45. Вывод записей справочника «Товары», расположенных в порядке иерархии

В результате выполнения этого запроса записи справочника будут расположены в порядке иерархии – начиная от самых верхних корневых записей до самых последних элементов в цепочке иерархии (рис. 1.39).

Рис. 1.39. Вывод записей справочника «Товары», расположенных в порядке иерархии

Теперь покажем, как получать запросом реквизиты иерархического справочника с иерархией групп и элементов. Справочник Товары в демонстрационной конфигурации имеет реквизит Производитель, свойство Использование которого установлено в значение Для элемента.

Следует учитывать тот факт, что реквизиты, которые используются только для элементов справочника, будут содержать значение NULL в записях, которые являются группами. Аналогично реквизиты, у которых свойство Использование установлено в значение Для группы, будут содержать NULL в записях-элементах. Важно понимать, что значение NULL не является нулем или пустой строкой. Значения данного типа обозначают отсутствующие значения или значения, не имеющие смысла.

Для примера выполним запрос, в котором для записей, содержащих значение NULL в поле Производитель, выводится строка «NULL». В противном случае выводится содержимое поля Производитель (листинг 1.46).

Листинг 1.46. Вывод значения реквизита иерархического справочника

Для формирования поля выборки Производитель используется операция выбора (ВЫБОР (КОГДА … ТОГДА) ИНАЧЕ … КОНЕЦ). В этой операции после ключевого слова КОГДА записывается условие выбора, после ключевого слова ТОГДА следует значение поля выборки в случае, если условие истинно. В общем случае в операции выбора может указываться неограниченное количество альтернативных одиночных выборов КОГДА … ТОГДА. Значение выражения, указанного после слова ИНАЧЕ, используется в качестве результата операции выбора в том случае, если ни одно из ранее указанных альтернативных условий выбора не было выполнено.

В результате выполнения запроса мы видим, что для записей, являющихся группами

(Обувь, Детская обувь, Продукты), в поле выборки запроса Производитель выводится строка «NULL», а для элементов справочника, не являющихся группой, выводится содержимое поля Производитель (рис. 1.40).

Рис. 1.40. Вывод реквизитов иерархического справочника

При этом значения этого поля для некоторых записей (Пинетки, Кроссовки, Сметана) содержат пустую строку, но это не значение NULL – просто для этих элементов справочника значение реквизита Производитель было не заполнено (см. рис. 1.37).

Содержание

  1. Место предложения ВЫБРАТЬ в структуре запроса
  2. Примеры запросов с предложением ВЫБРАТЬ
  3. Идем дальше

В данной статье рассмотрено предложение ВЫБРАТЬ, его место и роль в языке запросов 1С:Предприятия 8.

Предложение ВЫБРАТЬ является единственным обязательным элементом любого запроса, поэтому изучение языка запросов начинается именно с него. Основная цель предложения ВЫБРАТЬ заключается в том, чтобы указать поля выборки, которые должны попасть в результат запроса.

Ниже рассмотрены следующие темы:

Место предложения ВЫБРАТЬ в структуре запроса

Структуру запроса 1С:Предприятия 8 можно представить в виде следующей схемы:

Из приведенной схемы можно сделать следующие выводы:

  • В любом запросе должно быть хотя бы одно предложение ВЫБРАТЬ.
  • В списке полей выборки должно быть описание хотя бы одного поля выборки, которое в общем случае является выражением.

Примеры запросов с предложением ВЫБРАТЬ

1. Выборка всех полей (кроме виртуальных) из таблиц

Вместо перечисления списка полей можно указать звездочку («*») и тогда в результат запроса попадут все поля таблицы-источника, кроме виртуальных. Например:

//обращение к таблице справочника
ВЫБРАТЬ * ИЗ Справочник.Номенклатура

//обращение к таблице документа
ВЫБРАТЬ * ИЗ Документ.РасходныйКассовыйОрдер

//обращение к основной таблице регистра накопления
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании

//обращение к виртуальной таблице регистра накопления
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании.Обороты

Замечание: В языке запросов есть возможность обойтись без предложения ИЗ, если описание поля содержит полный путь к нему с указанием таблицы-источника, например,

//выборка всех невиртуальных полей из таблицы справочника
ВЫБРАТЬ Справочник.Номенклатура.*

//выборка определенных полей из таблицы справочника
ВЫБРАТЬ
Справочник.Номенклатура.Код,
Справочник.Номенклатура.Наименование,
Справочник.Номенклатура.Представление //виртуальное поле

2. Выборка только определенных полей из таблиц

Самым обычным способом является перечисление нескольких полей из таблицы-источника запроса, тогда только эти поля попадут в результат запроса.

//обращение к таблице справочника
ВЫБРАТЬ Код, Наименование, Артикул, СтранаПроисхождения
ИЗ Справочник.Номенклатура

//обращение к таблице документа
ВЫБРАТЬ Номер, Дата, ПодразделениеКомпании, СуммаДокумента
ИЗ Документ.РасходныйКассовыйОрдер

3. Виртуальные поля

Некоторые поля в таблицах-источниках виртуальные, например, поле «Представление» для таблицы справочника и документа, или поле «МоментВремени» для документа. Это значит, что они не хранятся в базе данных, а генерируются «на лету». Виртуальные поля не включаются в результат запроса, когда вместо списка полей указана звездочка («*»), их нужно указывать явно, например «ВЫБРАТЬ *, Представление ИЗ Справочник.Товары». Такое решение было принято для ускорения выполнения классического запроса «ВЫБРАТЬ * ИЗ. ». В этом случае не требуется генерировать представления для элементов справочников и документов, следовательно запросы будут выполняться быстрее.

//обращение к таблице справочника (выбрать два обычных поля и одно виртуальное)
ВЫБРАТЬ Код, Наименование, Представление
ИЗ Справочник.Номенклатура

//обращение к таблице документа (выбрать все невиртуальные поля и два виртуальных)
ВЫБРАТЬ *, Представление, МоментВремени
ИЗ Документ.РасходныйКассовыйОрдер

4. Разыменование ссылочных полей

В 1С:Предприятии 8 допускается обращение к свойствам объектов через одну или несколько точек, например, «Номенклатура.Поставщик.Страна». Это позволяет значительно упростить написание запросов. Рекомендуется всегда пользоваться разыменованием полей там, где это возможно, чтобы не усложнять запросы лишними конструкциями.

//обращение к свойству объекта через одну точку
ВЫБРАТЬ
Ссылка,
ЮрФизЛицоКонтрагента . ИНН,
ПодразделениеКомпании . Код
ИЗ Документ.РасходныйКассовыйОрдер

//обращение к свойствам объектов через несколько точек
ВЫБРАТЬ
Ссылка,
Ответственный . ОсновнойБанковскийСчет . Банк . КоррСчет
ИЗ Документ.АвансовыйОтчет

5. Псевдонимы полей (ключевое слово КАК / AS)

Для поля может быть назначен псевдоним с помощью ключевого слова КАК. Это позволяет обращаться к полю по псевдониму при указании итогов и порядка сортировки, а также при обходе выборки из результата запроса, например:

ВЫБРАТЬ
Ссылка КАК Документ,
Ответственный КАК МатериальноОтветственный
ИЗ Документ.АвансовыйОтчет
УПОРЯДОЧИТЬ ПО МатериальноОтветственный

Ключевое слово КАК является необязательным, то есть вышеприведенный запрос можно записать так:

ВЫБРАТЬ
Ссылка Документ,
Ответственный МатериальноОтветственный
ИЗ Документ.АвансовыйОтчет

6. Обращение к табличной части как вложенной таблице

В этом случае поле результата запроса будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе табличной части.

//получение табличной части как вложенной таблицы результата запроса
ВЫБРАТЬ Номер, Дата, Товары
ИЗ Документ.АвансовыйОтчет

//получение нескольких колонок табличной части как вложенной таблицы
ВЫБРАТЬ Номер, Дата, Товары.(Номенклатура, Количество)
ИЗ Документ.АвансовыйОтчет

Обратите внимание, что если выполнить следующий запрос, то в результате запроса будет две вложенные таблицы: в первой — одна колонка Номенклатура, а во второй — колонка Количество:

ВЫБРАТЬ Номер, Дата, Товары.Номенклатура, Товары.Количество
ИЗ Документ.АвансовыйОтчет

7. Обращение к табличной части как таблице-источнику

При таком способе обращения имя вложенной таблицы фигурирует в имени таблицы-источника (предложение ИЗ или полные имена полей) и в результате запроса нет вложенных таблиц.

//выборка всех полей из табличной части
ВЫБРАТЬ * ИЗ Документ.АвансовыйОтчет.Товары

// выборка определенных полей из табличной части
ВЫБРАТЬ Номенклатура, Количество, Цена, Сумма
ИЗ Документ.АвансовыйОтчет.Товары

//задание псевдонимов для полей табличной части
ВЫБРАТЬ Документ.АвансовыйОтчет.Товары.(Номенклатура, Сумма КАК СуммаПоСтроке)

//обращение к реквизитам документа и реквизитам табличной части (поле Ссылка)
ВЫБРАТЬ
Ссылка.Номер, Ссылка.Дата, Ссылка.Ответственный, //реквизиты документа
Номенклатура, Количество, Цена, Сумма //реквизиты табличной части
ИЗ Документ.АвансовыйОтчет.Товары

8. Ключевое слово РАЗЛИЧНЫЕ / DISTINCT

Ключевое слово РАЗЛИЧНЫЕ позволяет оставить в результате запроса только отличающиеся строки.

ВЫБРАТЬ РАЗЛИЧНЫЕ Ответственный
ИЗ Документ.АвансовыйОтчет

9. Ключевое слово ПЕРВЫЕ / TOP

Данное ключевое слово позволяет ограничить выборку несколькими первыми записями. Часто это ключевое слово применяется в комбинации с сортировкой (предложение УПОРЯДОЧИТЬ ПО).

ВЫБРАТЬ ПЕРВЫЕ 10 Номер, Дата, СуммаДокумента
ИЗ Документ.АвансовыйОтчет
УПОРЯДОЧИТЬ ПО СуммаДокумента УБЫВ

10. Выражения в списке полей выборки

В качестве описания поля выборки может быть выражение, использующее следующие элементы:

  • Литералы типов: число, строка (в кавычках), булево (значения Истина и Ложь), Null, Неопределено. [ Замечание : Чтобы указать литерал типа «дата», можно воспользоваться ключевым словом языка запросов ДАТАВРЕМЯ или передать дату через параметр запроса].
  • Параметры запроса (со знаком &)
  • Имя поля
  • Имя табличной части
  • Разыменование ссылочного поля (через одну или несколько точек)
  • Арифметические операции (+, -, /, *) [ Замечание : операция получения остатка % в языке запросов не поддерживается]
  • Операция конкатенации строк (+) [ Замечание : операцию конкатенации нельзя использовать для виртуальных полей]
  • Встроенные функции языка запросов (ДЕНЬ, МЕСЯЦ, ГОД и т.д.)
  • Агрегатные функции (СУММА, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, КОЛИЧЕСТВО)
  • Операция выбора ВЫБОР / CASE — позволяет получить одно из возможных значений в соответствии с указанными условиями.
  • Операция приведения типов ВЫРАЗИТЬ / CAST

Ниже приведено несколько примеров с выражениями в списке полей выборки:

//арифметические операции
ВЫБРАТЬ
Номенклатура,
Количество * Цена КАК РасчСумма1,
Сумма / Количество КАК РасчСумма2
ИЗ Документ.АвансовыйОтчет.Товары

//литералы типа «булево», «число», «строка», «дата»
ВЫБРАТЬ Истина, Ложь, 10.5, «Текст», ДАТАВРЕМЯ(2003,12,25)

//конкатенация строк
ВЫБРАТЬ «Сотрудник » + Ответственный.Наименование
ИЗ Документ.АвансовыйОтчет

//агрегатные функции
ВЫБРАТЬ
ПодразделениеКомпании,
СУММА(СуммаДокумента),
МАКСИМУМ(СуммаДокумента),
МИНИМУМ(СуммаДокумента),
СРЕДНЕЕ(СуммаДокумента),
КОЛИЧЕСТВО(*)
ИЗ Документ.АвансовыйОтчет
СГРУППИРОВАТЬ ПО ПодразделениеКомпании

//операция выбора
ВЫБРАТЬ Наименование,
ВЫБОР
КОГДА СтранаПроисхождения.Наименование = «КИТАЙ» ТОГДА «Азия»
КОГДА СтранаПроисхождения.Наименование = «ТАЙВАНЬ» ТОГДА «Азия»
КОГДА СтранаПроисхождения.Наименование = «США» ТОГДА «Америка»
КОГДА СтранаПроисхождения.Наименование = «КАНАДА» ТОГДА «Америка»
ИНАЧЕ «Другое»
КОНЕЦ КАК Страна
ИЗ Справочник.Номенклатура

//операция приведения типов
ВЫБРАТЬ
Ссылка,
Номенклатура,
ВЫРАЗИТЬ(Сумма / 3 КАК Число(5,2)) КАК ТретьСуммы
ИЗ Документ.АвансовыйОтчет.Товары

Таким образом, предложение ВЫБРАТЬ является важнейшим элементом языка запросов, поскольку позволяет указать требуемые поля результата запроса. Гибкие возможности предложения ВЫБРАТЬ позволяют использовать язык запросов для решения самых разнообразных задач.

В этой статье мы разберем такую тему, как вложенные таблицы в языке запросов 1С.

В полях выборки запроса можно использовать вложенную таблицу источника запроса. Например, у документа «Оказание услуг», есть табличная часть Услуги, так вот, эту табличную часть тоже можно вывести в поле выборки. Сейчас Вы увидите, как это можно реализовать.

В своей учебной базе я запущу консоль запросов, открою конструктор запросов и выберу таблицу «Оказание Услуг».

Раскроем эту таблицу

И в ней мы видим табличную часть «Услуги».

Вот всю эту табличную часть и выберем.

Как видите, вся табличная часть услуги полностью выбралась в поля.

Обращаю Ваше внимание, что табличная часть, по сути, идет как отдельное поле, которое называется «Услуги» и тип которого будет «РезультатЗапроса». Научимся использовать вложенную таблицу в запросе.

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

Нажмем кнопку ОК в конструкторе, и посмотрим как будет выглядеть наш запрос.

Как видите, в запросе после поля «Услуги» идет точка, а за ней в скобках перечислены выбранные поля.

На рисунке мы видим, что все выбранные поля табличной части документа перечислена через запятую в поле «Услуги». Не во всех консолях запросов бывает такое отображение как на рисунке выше, иногда может просто идти надпись «ТаблицаЗначений«.

Ещё интересный момент, у вложенной таблицы можно вместо полей поставить звездочку, тогда выйдут все поля табличной части. Это нельзя сделать в конструкторе, только вручную в запросе. Запрос приобретет следующий вид:

Посмотрим, как выполнится такой запрос.

Единственно, что эта звездочка у нас не сохранится, если открыть конструктор запроса.

Мы научились делать запрос с вложенной таблицей в консоле, теперь научимся использовать вложенную таблицу в выборке

В действительности не так сложно обратится при обработке запроса к вложенной таблице. Вы просто обращаетесь к выборке по названию вашей таблицы, и получаете переменную с типом «РезультатЗапроса». А потом обрабатываете ее как обычный результат запроса: хотите, получайте выборку, хотите, делайте выгрузку.

Ниже приведу небольшой пример кода, в котором осуществляется работа с вложенной таблицей:

&НаСервере
Процедура ЗаполнитьНаСервере ()
Запрос = Новый Запрос ;
Запрос . Текст = «ВЫБРАТЬ
| ПродажаТовара.Ссылка,
| ПродажаТовара.Товары.(
| Товар,
| Количество
| )
|ИЗ
| Документ.ПродажаТовара КАК ПродажаТовара» ;
Выборка = Запрос . Выполнить (). Выбрать ();
Пока Выборка . Следующий () Цикл
ВерхняяСтрокаДерева = ПродажаТоваров . ПолучитьЭлементы ();
НоваяСтрока = ВерхняяСтрокаДерева . Добавить ();
НоваяСтрока . Ссылка = Выборка . Ссылка ;
ТаблТовары = Выборка . Товары ;
ВыборкаТоваров = ТаблТовары . Выбрать ();
Пока ВыборкаТоваров . Следующий () Цикл
ДочерняяСтрокаДерева = НоваяСтрока . ПолучитьЭлементы ();
СтрокаТоваров = ДочерняяСтрокаДерева . Добавить ();
СтрокаТоваров . Ссылка = ВыборкаТоваров . Товар ;
СтрокаТоваров . Количество = ВыборкаТоваров . Количество ;
КонецЦикла;
КонецЦикла;
КонецПроцедуры

Разъясню вышеприведенный код.

Первым делом мы получили линейную выборку, и обходим эту выборку в цикле, в котором создаем верхнюю строку дерева значений (оно на форме), и в неё записываем ссылку на наш документ.

А дальше самое интересное, можете даже посмотреть это потом в отладчике самостоятельно, мы обращаемся к полю выборки Товары, и записываем для удобства это поле в отдельную переменную ТаблТовары. Данная переменная имеет тип «РезультатЗапроса». И можно спокойно получить выборку этого результата. Что мы и делаем. Осталось обойти эту выборку с помощью функции следующий и цикла пока.

А внутри этого цикла будем обращаться к полям выборки как к полям вложенной таблицы, и записывать их в дочерние строки дерева с формы.

Вот какой результат будет возвращать этот код

Остались вопросы?

Вы ответите на них сами, когда изучите мой курс «Запросы в 1С для начинающих». Где эти и многие другие вопросы рассматриваются более подробно. Вся информация дается в простой и доступной форме и понятна даже тем, кто особо не знаком с программированием в 1С.

Промо-код на скидку в 20%: hrW0rl9Nnx

Поддержите мой проект перечислив любую сумму

Как в запросе отобрать только табличные части с указанным условием и не заполненные. Автор статьи: Гений 1С | Редакторы:
Последняя редакция №3 от 23.08.06 |

Ключевые слова: табличная часть,запрос

Как то мне довелось править отчет, написанный не мной. Там выдался список всех сотрудников у которых есть дети, родившиеся после указанного года.

Ну и меня попросили переделать, чтобы в список попадали не только те сотрудники, у которых есть дети нужного возраста, но и сотрудники без детей и галочкой отмечать таких бездетных сотрудников.

Исходный запрос был таким:

Можно было убрать условие где, тогда бы в результат попали все табличные части, даже не заполненные. Но тогда бы терялось удобство использования отбора и скорость отчета бы гораздо уменьшилась. Мне бы пришлось программно перебирать таблицу значений Дети и проверять год рождения.

В результате я изменил условие на противоположное и добился нужного:

Для пустой табличной части условие в скобках давало ложь, НЕ превращало его в истину. Все нужные данные попадали.

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

Идем дальше

Но лучше всего и надежнее использовать другой подход. Если уж вам хочется таблиц значений, нужно написать этот запрос так:

Понравилась статья? Поделить с друзьями:
  • Как в запросе проверить реквизит на пустое значение 1с
  • Как в личном кабинете сбера посмотреть реквизиты карты
  • Как в мобильном банке посмотреть реквизиты своей карты
  • Как в мобильном банке узнать реквизиты своей карты втб
  • Как в обработке проведения изменить реквизит документа