Показать сообщение отдельно
Старый 25.01.2008, 19:35   #17  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
универсальная параметрическая штучка
Тоже наконец "посчастливилось" повозиться с рисованием сетки и расчетом высоты вертикальных "палок" (которые shapes). С благодарностью воспринял идеи этой темы и, творчески передрав и реорганизовав код из упоминаемого источника (отчет SalesPurchInvoice_RU, метод prepareDynamicSection), оформил метод с параметрами. Мне нужно было рисовать сразу 3 разные сетки, поэтому вопрос о некоторой универсальной процедуре естественным образом встал сам собой. Получившийся метод я гордо поместил в класс Global и теперь тихо радуюсь. Приглашаю к этой тихой радости всех желающих.

Параметры метода:
1. секция, подлежащая динамическому расчету;
2. контейнер пар "control - значение" (где "значение" - характерная "максимальная" строка, по которой происходит расчет требуемой высоты контрола);
3. минимально допустимая высота элемента в секции (ниже которой не опускаемся, чтобы не было очень низких строк; unit - 1/100 mm, т.е. значение, например, 1200 соответствует в миру 12 миллиметрам)

Каждая пара "контрол - значение" в свою очередь тоже контейнер. Кол-во передаваемых пар - по вашему желанию. Может быть достаточно и одного контрола, потенциально самого высокого в секции в плане DynamicHeight. Но можно - для уверенности - перечислить и все имеющиеся в секции контролы, задав им в качестве значения соответствующие поля таблиц или дисплей-методы.

Метод, помещенный в класс Global:
X++:
static void prepareReportDynamicSection( ReportSection   _section,
                                         container       _pairsControlValue,
                                         int             _minHeight100mm = 0)
{
    ReportControl       reportControl;
    ReportShapeControl  reportShapeControl;
    Counter             i;
    int                 childNodesCount;
    int                 maxHeight100mm,
                        maxTop100mm;
    str                 currControl,
                        currValue;

    void processControl( ReportControl _control, str _fieldValue )
    {
        int ht100, tp100;
        ;
        ht100 = max( _control.heightOfWordWrappedString100mm( _fieldValue ),
                     _control.heightOfWordWrappedString100mm(' '), // ' \n \n \n '
                     _minHeight100mm);

        tp100 = _control.top100mm();

        maxHeight100mm  = max( maxHeight100mm, ht100 );
        maxTop100mm     = max( maxTop100mm, tp100 );
    }
    ;

    for(i = 1; i <= conlen(_pairsControlValue); i++)
    {
        [currControl, currValue] = conpeek(_pairsControlValue, i);
        processControl( _section.controlName(currControl), currValue);
    }

    childNodesCount = _section.AOTchildNodeCount();

    for(i = 0; i < childNodesCount; i++)
    {
        reportControl = _section.controlNo(i);

        if (! reportControl)
            continue;

        if(reportControl.controlType() == ReportFieldType::BOX)
        {
            reportShapeControl = reportControl;

            if(reportShapeControl.type() != ShapeType::Horizontal)
            {
                reportShapeControl.height100mm(maxHeight100mm + 1 + maxTop100mm);
            }
            else
            {
                if(reportShapeControl.top100mm())
                {
                    reportShapeControl.top100mm(maxHeight100mm + 1 + maxTop100mm);
                }
            }
        }
        else
        {
            reportControl.height100mm(maxHeight100mm);
        }
    }
}
Примечание: Наличие вложенного метода processControl - не более, чем рудимент от первоначальной попытки декомпозиции задачи. При желании можно смело избавиться от него, перенеся необходимые операторы в общий цикл.

Пример вызова - в методе executeSection соответствующей секции:
X++:
public void executeSection()
{
    prepareReportDynamicSection
    ( this,
      [
            ['Control_1', element.getLineNum()  ],
            ['Control_2', element.getItemDescr()],
            ['Control_3', table1.field1         ],
            ['Control_4', 'bla-bla-bla'         ]
      ],
      1200 );

    super();
}
За это сообщение автора поблагодарили: mazzy (5), Sergey Petrov (1), star52 (1).