Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
19 апр 2024, 07:35

Построение макета документа с группировкой

Автор Koriolan, 22 мая 2016, 20:45

0 Пользователей и 1 гость просматривают эту тему.

Koriolan

Добрый день.
Уважаемые форумчане, прошу помощи в технической реализации такой вот проблемы. Есть документ "Прием на работу", табличная часть которого имеет следующую структуру (см. рисунок 1)

напротив каждой фамилии содержится название должности.
В печатном документе необходимо реализовать группировку фамилий по должностям. Интересующая часть макета должна иметь вид (см. рисунок 2):

Для вывода данных документа создал следующий запрос:
Макет = Документы.ПрийомНаРоботу.ПолучитьМакет("Друкувати");
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ПрийомНаРоботу.Дата,
    |    ПрийомНаРоботу.Номер,
    |    ПрийомНаРоботу.Період.НазваПеріодуУРодовомуВідмінку КАК Період,
    |    ПрийомНаРоботу.СписокФізичнихОсіб.(
    |        ФізичнаОсоба.ПрізвищеРодовийВідмінок,
    |        ФізичнаОсоба.ІмяРодовийВідмінок,
    |        ФізичнаОсоба.ПоБатьковіРодовийВідмінок,
    |        ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку КАК Посада,
    |        НомерСтроки
    |    )
    |ИЗ
    |    Документ.ПрийомНаРоботу КАК ПрийомНаРоботу
    |ГДЕ
    |    ПрийомНаРоботу.Ссылка В(&Ссылка)
    |    И ПрийомНаРоботу.СписокФізичнихОсіб.Бухгалтерія = &Бухгалтерія";
    Запрос.Параметры.Вставить("Ссылка", Ссылка);
    Запрос.Параметры.Вставить("Бухгалтерія", Истина);
    Выборка = Запрос.Выполнить().Выбрать();


в котором "СписокФізичнихОсіб" как раз и есть название интересующей табличной части документа.

у меня получается вывести только в следующем виде:


,что не совсем красиво.

Подскажите, как перестроить запрос или сформировать код вывода, чтобы документ приобрел нормальный вид. Подозреваю, что решение лежит где-то совсем на поверхности (или другая структура запроса, или сам код вывода), но я самоучка, поэтому многого еще не знаю. Если для ответа нужен код модуля менеджера, то его часть, в которой проблема здесь:
Процедура Друкувати(ТабДок, Ссылка) Экспорт
    //{{_КОНСТРУКТОР_ПЕЧАТИ(Друкувати)
    Макет = Документы.ПрийомНаРоботу.ПолучитьМакет("Друкувати");
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ПрийомНаРоботу.Дата,
    |    ПрийомНаРоботу.Номер,
    |    ПрийомНаРоботу.Період.НазваПеріодуУРодовомуВідмінку КАК Період,
    |    ПрийомНаРоботу.СписокФізичнихОсіб.(
    |        ФізичнаОсоба.ПрізвищеРодовийВідмінок,
    |        ФізичнаОсоба.ІмяРодовийВідмінок,
    |        ФізичнаОсоба.ПоБатьковіРодовийВідмінок,
    |        ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку КАК Посада
    |    )
    |ИЗ
    |    Документ.ПрийомНаРоботу КАК ПрийомНаРоботу
    |ГДЕ
    |    ПрийомНаРоботу.Ссылка В(&Ссылка)
    |    И ПрийомНаРоботу.СписокФізичнихОсіб.Бухгалтерія = &Бухгалтерія";
    Запрос.Параметры.Вставить("Ссылка", Ссылка);
    Запрос.Параметры.Вставить("Бухгалтерія", Истина);
    Выборка = Запрос.Выполнить().Выбрать();
   
    Заголовок = Макет.ПолучитьОбласть("Заголовок");
    ШапкаНаказу = Макет.ПолучитьОбласть("ШапкаНаказу");
    ПунктНаказу = Макет.ПолучитьОбласть("ПунктНаказу");
    Підпункт = Макет.ПолучитьОбласть("Підпункт");
    Підвал = Макет.ПолучитьОбласть("Підвал");
   
    ТабДок.Очистить();

    ВставлятьРазделительСтраниц = Ложь;
    Пока Выборка.Следующий() Цикл
        Если ВставлятьРазделительСтраниц Тогда
            ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;

        //Заголовок   
        ТабДок.Вывести(Заголовок);
       
        //ШапкаНаказу
        ШапкаНаказу.Параметры.ДатаНаказу = Формат(Выборка.Дата,"ДЛФ=DD");
        ШапкаНаказу.Параметры.НомерНаказу = Выборка.Номер;
        ШапкаНаказу.Параметры.ПеріодВРодовомуВідмінку = Выборка.Період;
        ШапкаНаказу.Параметры.ДатаНаказуРік = Формат(Выборка.Дата,"ДФ=yyyy");
       
        ТабДок.Вывести(ШапкаНаказу, Выборка.Уровень());
       
        //ПунктНаказу
        ВыборкаСписокФізичнихОсіб = Выборка.СписокФізичнихОсіб.Выбрать();
       
        Пока ВыборкаСписокФізичнихОсіб.Следующий() Цикл
           
            ПунктНаказу.Параметры.НазваПосадиВЗнахідномуВідмінку = НРег(ВыборкаСписокФізичнихОсіб.Посада);
            // Сода нужно вывести список фамилий
            ТабДок.Вывести(ПунктНаказу, ВыборкаСписокФізичнихОсіб.Уровень());
           
        КонецЦикла;
       
       

        ВставлятьРазделительСтраниц = Истина;
    КонецЦикла;
    //}}
КонецПроцедуры



Заранее благодарен за ответ.

Kironten

В двух словах: Надо делать группировку в запросе по полю "Посада" и делать обход по группировкам:
ВыборкаГруппировка = Запрос.Выполнить.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаГруппировка.Следующий() Цикл
// тут вывод пунктов 1. 2. и т.д
ВыборкаДетальныеЗаписи = ВыборкаГруппировка.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// тут вывод пунктов 1.1, 1.2, 1.3, 2.1, 2.2 и т.д
КонецЦикла
КонецЦикла


Koriolan

Цитата: Kironten от 24 мая 2016, 12:53
В двух словах: Надо делать группировку в запросе по полю "Посада" и делать обход по группировкам:

Спасибо. Попробовал последовать Вашему совету. Вот что получилось:

В модуле у меня вышло два запроса:
1. Первый запрос отвечает за выборку данных для "шапки приказа". Там все просто и работает, если смотреть в отдельности.

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


2. Второй запрос выбирает и группирует данные табличной части. (это мое понимание Вашего совета):

Запрос0 = Новый Запрос;
Запрос0.Текст =
"ВЫБРАТЬ
| ПрийомНаРоботуСписокФізичнихОсіб.ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку КАК НазваПосадиВЗнахідномуВідмінку,
| ПрийомНаРоботуСписокФізичнихОсіб.ФізичнаОсоба.Наименование КАК ФізичнаОсобаНаименование
|ИЗ
| Документ.ПрийомНаРоботу.СписокФізичнихОсіб КАК ПрийомНаРоботуСписокФізичнихОсіб
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПрийомНаРоботу КАК ПрийомНаРоботу
| ПО ПрийомНаРоботуСписокФізичнихОсіб.Ссылка = ПрийомНаРоботу.Ссылка
|ГДЕ
| ПрийомНаРоботу.Ссылка = &Ссылка
| И ПрийомНаРоботуСписокФізичнихОсіб.Бухгалтерія = &Бухгалтерія
|
|СГРУППИРОВАТЬ ПО
| ПрийомНаРоботуСписокФізичнихОсіб.ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку,
| ПрийомНаРоботуСписокФізичнихОсіб.ФізичнаОсоба.Наименование
|
|УПОРЯДОЧИТЬ ПО
| НазваПосадиВЗнахідномуВідмінку,
| ФізичнаОсобаНаименование";
Запрос0.параметры.Вставить("Ссылка", Ссылка);
    Запрос0.Параметры.Вставить("Бухгалтерія", Истина);

(Пробовал было объединить оба запроса в один или перестроить второй запрос без левого соединения, но выдается сообщение, говорящее об ошибке при вызове метода контекста. Группировка по таблицам верхнего уровня и вложенным таблицам . :dfbsdfbsdf:)


Если просматриваю результат работы второго запроса во внешней обработке - дает необходимые данные, но когда пытаюсь вшить в код модуля и запустить его опять выводится сообщение об ошибке метода контекста. Неправильные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов.
как я понимаю, проблема в восприятии строки
ПрийомНаРоботу.Ссылка = &Ссылка
Кроме того конструктор запросов настоятельно добавляет в группировку еще и фамилии.

СГРУППИРОВАТЬ ПО
| ПрийомНаРоботуСписокФізичнихОсіб.ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку,
| ПрийомНаРоботуСписокФізичнихОсіб.ФізичнаОсоба.Наименование

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

Kironten

Подумал об одном, а написал другое...
Не СГРУППИРОВАТЬ ПО, а ИТОГИ ПО. Тогда мы получим группировку верхнего уровня, а не свертку по полю группировки.
Если уж совсем сложно, оставьте 2 запроса, в первый выбирайте данные для шапки, а во второй выберите табличную часть.
Запрос будет примерно такой:
Запрос0 = Новый Запрос;
Запрос0.Текст =
        "ВЫБРАТЬ
        |    ПрийомНаРоботуСписокФізичнихОсіб.ПосадаПоДокументах.НазваПосадиВЗнахідномуВідмінку КАК НазваПосадиВЗнахідномуВідмінку,
        |    ПрийомНаРоботуСписокФізичнихОсіб.ФізичнаОсоба.Наименование КАК ФізичнаОсобаНаименование
        |ИЗ
        |    Документ.ПрийомНаРоботу.СписокФізичнихОсіб КАК ПрийомНаРоботуСписокФізичнихОсіб
        |ГДЕ
        |    ПрийомНаРоботуСписокФізичнихОсіб.Ссылка = &Ссылка
        |    И ПрийомНаРоботуСписокФізичнихОсіб.Бухгалтерія
        |
        |УПОРЯДОЧИТЬ ПО
        |    НазваПосадиВЗнахідномуВідмінку,
        |    ФізичнаОсобаНаименование
        |ИТОГИ ПО
        |    НазваПосадиВЗнахідномуВідмінку";

        Запрос0.параметры.Вставить("Ссылка", Ссылка);
        ВыборкаГруппировка = Запрос0.Выполнить.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);


Ну а дальше выводите, как я писал ранее.

Koriolan

Логику запроса, кажется, схватил. Вот только остается проблема с параметром.

ПрийомНаРоботуСписокФізичнихОсіб.Ссылка = &Ссылка

По-прежнему идет ошибка несовместимости данных.

       
Добавлено: 25 мая 2016, 21:36


Кажется, решил.

Переписал проблемную строку запроса следующим образом:
ПрийомНаРоботуСписокФізичнихОсіб.Ссылка В(&Ссылка)
вместо
ПрийомНаРоботуСписокФізичнихОсіб.Ссылка = &Ссылка
и все заработало :zebzdr::zebzdr:

Спасибо всем за помощь.

Kironten

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

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск