AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
CRM
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.10.2008, 22:43   #1  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
О, больная тема! О, любимая мозоль!

Poleax, бросайте изучать ComExcelDocument_RU, начинайте изучать Excel!

Тогда вы будете знать, что для вставки пустой строки перед ячейкой не надо узнавать ее номер, чтобы потом скормить его методу-обертке, вставляющему i-ю строку в таблицу. Если танцевать от comRange, а не от вездесущего текстового букмарка ("test"), который на каждом шаге переводится всё в тот же comRange (который почему-то приговорен быть локальным в методах этого класса), то пустая строка перед comRange вставляется так:
Код:
comRange.EntireRow().Insert()
Это псевдокод. В реале это надо расписать, как полагается при трансляции с VBA в X++ - на двух строчках. Потом посчитайте, сколько строк лишнего кода выполнится в вашем алгоритме, перед тем как в таблице появится пустая строка.

P.S. При желании можно сократить кол-во строк до одной, если воcпользоваться последними достижениями в этой области

X++:
comEarlyBindingImitation( comRange,'EntireRow()','Insert()');
Подробности здесь: Gustav: Unsorted, или Записки DAX-дилетанта - II
Старый 10.10.2008, 12:43   #2  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
офф-топ
Цитата:
Сообщение от Посмотреть сообщение
бросайте изучать ComExcelDocument_RU, начинайте изучать Excel
Ну, вот как раз еще один поучительный пример под горячую руку.

Это код фирменного (со слоя dis) метода из класса ComExcelDocument_RU (DAX 3.0, SP4). Я добавил несколько своих комментариев (в исходном фирменном виде метод не содержит комментариев, а также самой последней строки кода):
X++:
void copyAndInsertRange(str _bookMark, int _workSheet = 1)
{
    COM         comRange, comRange1,
                comWorkSheet;

    int         colNumber, colsNumber;
    int         rowNumber, rowsNumber;
    ;

    if (! m_comDocument)
        throw error(strFmt("@DIS6401", this.getApplicationName()));

    comRange = this.findRange(_bookMark, _workSheet);
    if (! comRange)
    {
        return;
    }

    rowNumber  = comRange.row();
    comRange1  = comRange.rows();
    rowsNumber = comRange1.count();

    // вычитаем единицу... (продолжение см. ниже)
    rowNumber  = rowNumber - 1;

    colNumber  = comRange.column();
    comRange1  = comRange.columns();
    colsNumber = comRange1.count();

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

    comRange.copy();

    comRange1 = this.findRange(ComExcelDocument_RU::numToNameCell(colNumber, rowNumber), _workSheet);
    if (! comRange1)
    {
        return;
    }
    comRange1.select();

    m_comApplication.cutCopyMode(false);
*/
    comRange = comRange.entireRow();
    comRange.insert();

    // следующие арифметические упражнения - без комментариев... ррррр!
    // P.S. А впрочем все-таки скажу. 
    // Если бы в начале метода исходный comRange = this.findRange(_bookMark, _workSheet)
    // был сохранен в отдельную переменную, например, comRange0, 
    // то вместо следующего ужасающего comRange = this.findRange(... достаточно было бы простого
    // comRange = comRange0 - поскольку при вставке строк перед Range его адрес автоматически переопределяется!
    comRange = this.findRange(ComExcelDocument_RU::numToNameCell(colNumber, rowNumber + rowsNumber + 1) + ":" +
                              ComExcelDocument_RU::numToNameCell(colNumber + colsNumber - 1, rowNumber + 2*rowsNumber),
                              _workSheet);
    if (! comRange)
    {
        return;
    }

    comRange.copy();

    // ...чтобы потом вернуть эту вычтенную ранее единицу обратно (rowNumber + 1) :)
    comRange1 = this.findRange(ComExcelDocument_RU::numToNameCell(colNumber, rowNumber + 1), _workSheet);

    comRange1.select();

    comWorkSheet = this.getWorkSheet(_workSheet);
    if (comWorkSheet)
    {
        comWorkSheet.paste();
    }

//  а вот здесь этот оператор не помешает (при данном подходе)
    m_comApplication.cutCopyMode(false);
}
А это код нового метода, делающего ту же работу:
X++:
void copyAndInsertRangeNew(str _bookMark, int _workSheet = 1)
{
    COM         comRange, comRange1;

    int         rowsNumber;
    ;

    if (! m_comDocument)
        throw error(strFmt("@DIS6401", this.getApplicationName()));

    comRange = this.findRange(_bookMark, _workSheet);
    if (! comRange)
    {
        return;
    }

    rowsNumber = any2int(COM::createFromObject( comRange.Rows() ).Count());

    COM::createFromObject(comRange.EntireRow()).Insert();
    comRange1 = comRange.Offset(-rowsNumber);
    comRange.Copy(comRange1);
}
А это тот вид метода, к которому я призываю, чтобы наконец избавиться от элементов "защитного программирования" типа if (! m_comDocument) и if (! comRange) - не от всех, конечно, но от необоснованных:
X++:
void copyAndInsertRangeNew2(COM _comRange)
{
    COM         comRange1;
    int         rowsNumber;
    ;

    rowsNumber = any2int(COM::createFromObject( _comRange.Rows() ).Count());

    COM::createFromObject(_comRange.EntireRow()).Insert();
    comRange1 = _comRange.Offset(-rowsNumber);
    _comRange.Copy(comRange1);
}
Заметьте, что в таком виде метод вообще не нуждается в классе ComExcelDocument_RU и в статическом виде может быть помещен хоть в Global.

И в качестве постскриптума и для большей ясности - код VBA, который делает ту же работу, что и вышеприведенные методы X++:
Код:
 
Sub Macro1()
    Dim rng As Range
    Set rng = Worksheets(1).Range("B2:C4")
    
    rng.EntireRow.Insert
    rng.Copy rng.Offset(-rng.Rows.Count)
End Sub
За это сообщение автора поблагодарили: blokva (3), Poleax (2).
Теги
excel, документация, как правильно, ax3.0

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
как вывести номер строки в гриде? funnut DAX: Программирование 21 01.10.2012 16:33
Цветные строки в Grid Sergo DAX: База знаний и проекты 14 19.04.2012 10:02
При создании строки в закупке статус строки становится "Отменено" AlexUnik DAX: Функционал 4 27.09.2004 16:05
Буферные ячейки на складе - зачем? renat DAX: Функционал 16 01.04.2004 20:22
Функция "Удалить строки" Oks DAX: Функционал 1 03.07.2002 18:09

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

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