AXForum  
Вернуться   AXForum > Блоги > Gustav'ово бложище, или Записки DAX-дилетанта-III
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

Стараюсь писать про Аксапту, хотя частенько тянет в Офис
Оценить эту запись

Использование OWC Spreadsheet в диалоге

Запись от Gustav размещена 15.10.2009 в 17:49
Обновил(-а) Gustav 15.10.2009 в 23:40

Имеется диалог, при помощи которого пользователь задает параметры изменения срока службы у нескольких основных средств, которые в данный момент отфильтрованы и/или отмечены в гриде формы "Основные средства" (RAssetTable). Процесс инициируется кнопкой, расположенной на этой форме. Диалог выглядит так:

Название: LifeTimeOld.PNG
Просмотров: 3064

Размер: 2.7 Кб

После нажатия на кнопку ОК новое значение срока службы (как можно догадаться из рисунка - одно и то же) прописывается всем выбранным ОС - одному или нескольким, отмеченным в гриде при помощи мышки и клавиш Ctrl или Shift. Код, выполняющий эту работу, выглядит следующим образом ( (с) GMCS ):
X++:
void ChangeLifeTime()
{
    DialogRunBase           dialog = new Dialog();
    DialogField             dialogDate,dialogLifeTime,dialogStandardId;

    RAssetLifeTime          dialogLifeTimeValue;
    RAssetStandardId        dialogStandardValue;
    TransDate               dialogDateValue;
    int                     i = 0;
    common                  urRec;
    RassetTable             urRAssetTable;
    RassetStandards         urRassetStandards;
    ;
    urRec = RAssetTable_ds.getFirst(1);
    if (! urRec) urRec = RAssetTable_ds.cursor();
    if (urRec)
    {
        dialog.caption("Новые значения");
        DialogDate = dialog.addField(typeId(TransDate));
        DialogDate.value(today());
        dialogStandardId = dialog.addField(typeId(RAssetStandardId));
        dialogLifeTime = dialog.addField(typeId(RAssetLifeTime));

        dialogDate.widthMode(formwidth::ColumnWidth);
        dialogStandardId.widthMode(formwidth::ColumnWidth);
        dialogLifeTime.widthMode(formwidth::ColumnWidth);

        if (dialog.run())
        {
            dialogDateValue =           DialogDate.value();
            dialogStandardValue =       dialogStandardId.value();
            dialogLifeTimeValue =       dialogLifeTime.value();
            if (! (dialogDateValue && dialogStandardValue && dialogLifeTimeValue))
            {
                checkFailed(strFmt("Заполните все поля"));
                return;
            }
            if (! RAssetStandardTable::Find(dialogStandardValue))
            {
                checkFailed(strFmt("Значение '%1' не найдено в таблице модели учета", dialogStandardValue));
                return;
            }

            While (urRec)
            {
                i++;
                RAssetTable_ds.findRecord(urRec);
                if (RAssetTable_ds)
                {
                    historyDialog.lifetimeDate(dialogDateValue);
                    ttsBegin;
                    urRassetStandards = RassetStandards::find(
                        urRec.(fieldNum(RAssetTable,AccountNum)),dialogStandardValue, true);
                    urRassetStandards.Lifetime = dialogLifeTimeValue;
                    urRassetStandards.update(historyDialog);
                    ttsCommit;
                    RAssetTable_ds.reread();
                    RAssetTable_ds.refresh();
                }

                urRec = RAssetTable_ds.getNext();
            }
            info(strFmt("Операция по смене срока службы по %1 ОС  модели %2 успешно завершена", int2Str(i),dialogStandardValue));

        }
    }
}
Помимо изменения поля LifeTime в таблице RAssetStandards для соответствующего ОС, происходит еще и сохранение записи в таблице истории RAssetLifeHist. Переменная historyDialog класса RAssetHistoryDialog определена в ClassDeclaration формы RAssetTable и предназначена для передачи в метод update таблицы RAssetStandards, в котором в конечном счете и выполняется вызов метода, отвечающего за сохранение в истории записи об изменении срока службы ОС.

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

Нужно было как-то модифицировать исходный диалог, чтобы приспособить его к новым требованиям. Был выбран вариант с ActiveX - OWC Spreradsheet, и после внесения изменений диалог стал выглядеть так:

Нажмите на изображение для увеличения
Название: LifeTimeNew.PNG
Просмотров: 493
Размер:	19.1 Кб
ID:	9

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

Код будет приведен в первом комментарии, так как попытка поместить его в это стартовое сообщение опять упёрлась в ограничение на 10К символов. В свою очередь, в комментариях не хотят размещаться картинки, но вроде я уже все необходимые разместил в этом сообщении...
Размещено в Без категории
Просмотров 161648 Комментарии 1
Всего комментариев 1

Комментарии

  1. Старый комментарий
    Аватар для Gustav
    А вот и модифицированный код:
    X++:
    void ChangeLifeTime()
    {
        DialogRunBase           dialog = new Dialog();
        DialogField             dialogDate,dialogLifeTime,dialogStandardId;
    
        RAssetLifeTime          dialogLifeTimeValue;
        RAssetStandardId        dialogStandardValue;
        TransDate               dialogDateValue;
        int                     i = 0;
        common                  urRec;
        RassetTable             urRAssetTable;
        RassetStandards         urRassetStandards;
    
        DialogGroup             dialogGroupSS;  // группа, в которую помещается Spreadsheet
        FormGroupControl        groupSS;        // та же группа, только уже как контрол
        FormActiveXControl      ss;             // собственно Spreadsheet
    
        COM                     range;
        COM                     temp;
        COM                     currCell;
        COMVariant              cv;
    
        int                     lastRow;
        int                     row;
    
        RassetId                currRassetId;
        RAssetLifeTime          currLifeTime;
    
        ;
        urRec = RAssetTable_ds.getFirst(1);
        if (! urRec) urRec = RAssetTable_ds.cursor();
        if (urRec)
        {
            dialog.caption("Новые значения");
    
            // KKu, 22.09.2009 --> модификация на случай разных сроков службы
            dialog.addGroup('Основные параметры');
            // KKu, 22.09.2009 <--
    
            DialogDate = dialog.addField(typeId(TransDate));
            DialogDate.value(today());
            dialogStandardId = dialog.addField(typeId(RAssetStandardId));
            dialogLifeTime = dialog.addField(typeId(RAssetLifeTime));
    
            dialogDate.widthMode(formwidth::ColumnWidth);
            dialogStandardId.widthMode(formwidth::ColumnWidth);
            dialogLifeTime.widthMode(formwidth::ColumnWidth);
    
            // KKu, 22.09.2009 --> модификация на случай разных сроков службы
            // без группы Spreadsheet показывался неуправляемо
            // только при помощи группы он более-менее обуздался
            dialogGroupSS = dialog.addGroup('В случае разных сроков службы');
            groupSS = dialogGroupSS.formGroup();
            groupSS.addControl(FormControlType::ActiveX, 'MySpreadSheet');
    
            dialog.doInit();
    
            ss = dialog.formRun().design().controlName('MySpreadSheet');
            ss.className('{0002E541-0000-0000-C000-000000000046}');     // Microsoft Office Spreadsheet 10.0
            //ss.className('{0002E559-0000-0000-C000-000000000046}');   // Microsoft Office Spreadsheet 11.0
    
            ss.height(300);
            ss.width(600);
    
            // гасим ярлычки листов
            ss.DisplayWorkbookTabs(false);
    
            range = ss.Range('A1'); range.Value2('Инв. номер ОС');
            range = ss.Range('B1'); range.Value2('Новый срок службы');
            range = ss.Range('C1'); range.Value2('Инструкция');
    
            range = ss.Range('C2'); range.Value2('Если Вы хотите выполнить обновление');
            range = ss.Range('C3'); range.Value2('сроков службы для нескольких ОС');
            range = ss.Range('C4'); range.Value2('разными значениями сроков,');
            range = ss.Range('C5'); range.Value2('то поставьте "Срок службы" равным -1');
            range = ss.Range('C6'); range.Value2('в группе полей "Основные параметры"');
            range = ss.Range('C7'); range.Value2('и введите данные в колонки A и B,');
            range = ss.Range('C8'); range.Value2('начиная со строки 2.');
    
            range = ss.Range('A1:C1');
            temp = range.Font();
            temp.Bold(true);
    
            temp = range.EntireColumn();
            temp.AutoFit();
            // KKu, 22.09.2009 <--
    
            if (dialog.run())
            {
                dialogDateValue =           DialogDate.value();
                dialogStandardValue =       dialogStandardId.value();
                dialogLifeTimeValue =       dialogLifeTime.value();
                if (! (dialogDateValue && dialogStandardValue && dialogLifeTimeValue))
                {
                    checkFailed(strFmt("Заполните все поля"));
                    return;
                }
                if (! RAssetStandardTable::Find(dialogStandardValue))
                {
                    checkFailed(strFmt("Значение '%1' не найдено в таблице модели учета", dialogStandardValue));
                    return;
                }
    
                // KKu, 22.09.2009 --> модификация на случай разных сроков службы
                if (dialogLifeTimeValue != -1)
                // KKu, 22.09.2009 <--
                {
                    // старое продолжение
                    While (urRec)
                    {
                        i++;
                        RAssetTable_ds.findRecord(urRec);
                        if (RAssetTable_ds)
                        {
                            historyDialog.lifetimeDate(dialogDateValue);
                            ttsBegin;
                            urRassetStandards = RassetStandards::find(
                                urRec.(fieldNum(RAssetTable,AccountNum)),dialogStandardValue, true);
                            urRassetStandards.Lifetime = dialogLifeTimeValue;
                            urRassetStandards.update(historyDialog);
                            ttsCommit;
                            RAssetTable_ds.reread();
                            RAssetTable_ds.refresh();
                        }
    
                        urRec = RAssetTable_ds.getNext();
                    }
                }
                // KKu, 22.09.2009 --> модификация на случай разных сроков службы
                else
                {
                    // новое продолжение
    
                    // определяем последнюю строку
                    lastRow = xlRanges::countRows(range.CurrentRegion());
    
                    for (row=2; row <=lastRow; row++)
                    {
                        // читаем из Spreadsheet Инв.номер ОС
                        currCell = xlRanges::cellRC(range, row, 1, true);
                        cv = currCell.Value();
                        currRassetId = cv.bStr();
    
                        // читаем из Spreadsheet Новый срок службы
                        currCell = xlRanges::cellRC(range, row, 2, true);
                        cv = currCell.Value();
                        currLifeTime = cv.double();
    
                        urRAssetTable = RAssetTable::find(currRassetId);
                        if (urRAssetTable)
                        {
                            i++;
                            historyDialog.lifetimeDate(dialogDateValue);
                            ttsBegin;
                            urRassetStandards = RassetStandards::find(
                                urRAssetTable.AccountNum, dialogStandardValue, true);
                            urRassetStandards.Lifetime = currLifeTime; // dialogLifeTimeValue;
                            urRassetStandards.update(historyDialog);
                            ttsCommit;
                            info(strFmt('%1 --- %2', currRassetId, currLifeTime));
                        }
                    }
                }
                // KKu, 22.09.2009 <--
    
                info(strFmt("Операция по смене срока службы по %1 ОС  модели %2 успешно завершена", int2Str(i),dialogStandardValue));
            }
        }
    }
    Весь код метода, наверное, не так интересен - хотя бы потому, что его невозможно запустить в автономном режиме как джоб. Тем не менее, я привожу его полностью - хотя бы потому, что замена несущественного в рамках темы кода на комментарии вида "// bla-bla-bla" представляет собой дополнительную работу, которую мне делать не хочется

    В интересующих нас в данный момент строчках кода, относящихся к Spreadsheet, имеются вызовы двух статических методов моего класса xlRanges, который я планирую подробно рассмотреть в одном из ближайших сообщений своего блога. Пока же чисто справочно приведу эти методы "as is":
    X++:
    static int countRows(COM parentRange)
    {
        // COM parentRange может быть Excel.Application (подразумевается ActiveSheet) или Worksheet или Range
        // в случае Spreadsheet - Spreadsheet.Application или Worksheet или Range
    
        return any2int(COM::createFromObject( parentRange.Rows() ).Count());
    }
    
    static COM cellRC(COM parentRange, int row, int col, boolean forSpreadsheet = false)
    {
        // COM parentRange может быть Excel.Application (подразумевается ActiveSheet) или Worksheet или Range
        // в случае Spreadsheet - Spreadsheet.Application или Worksheet или Range
        // row и col могут быть меньше единицы (0 и отрицательные) - и для Excel, и для Spreadsheet
        // но меньше единицы - только для Range (не для Application, и не для Worksheet)
        // возвращает объект Range
        COM cells;
        ;
        cells = parentRange.Cells();
    
        if (! forSpreadsheet)
            // Excel
            return COM::createFromVariant( cells.Item( row, col ));
        else
            // Spreadsheet
            return cells.Item( row, col );
    }
    Запись от Gustav размещена 15.10.2009 в 17:50 Gustav is offline
    Обновил(-а) Gustav 16.10.2009 в 17:55
 


Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:00.