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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.01.2012, 13:03   #1  
Димитрий is offline
Димитрий
Участник
 
27 / 12 (1) ++
Регистрация: 10.08.2009
:( Excel. пустые ячейки
Доброго дня.

Сторонняя программа дает Excel-файл. Я его порезал убрав лишнее. Файл в аттаче. Суть в том, что есть данные в первом столбце и нет во втором. И вот такой код есть:

X++:
static void checkExcell(Args _args)
{
    FilePath path='';
    container conFilter = ["Файл  (*.xls)", "*.xls"];
    SysExcelApplication exappl;
    SysExcelCells excells;
    SysExcelWorksheets exsheets;
    SysExcelWorksheet exsheet;
    int row;
    real a,b;
    ;

    path = WinAPI::getOpenFileName(0,conFilter,"", "Укажите файл ",'',"");
    if (!path) return;

    exappl = SysExcelApplication::construct();
    exappl.workbooks().open(path);
    exsheets = exappl.workbooks().item(1).worksheets();
    exsheet = exsheets.itemFromNum(1);
    excells = exsheet.cells();

    for(row = 1;row<3;row++)
    {
        a = excells.item(row,1).value().double();
        //info(strfmt('%1',a));                          // строка 1
        b = excells.item(row,2).value().double();
        info(strfmt('%1',a));                            // строка 2  
        info(strfmt('%1',b));
    }

    exappl.quit();

}
Если закомментировать строку 1, но не 2 то будут выводиться одни данные. Если наоборот, то другие.
Во втором случае выводится ожидаемое. В первом же случае, вместо 0 (в ячейке 2-го столбца пусто) получаем данные из первого столбца.

Если в файле во второй колонке проставить значения, а потом удалить - все опять корректно работает.

Axapta 2009.

В 3-й такой проблемы не наблюдаю.
Вложения
Тип файла: xls Доп1.xls (13.5 Кб, 102 просмотров)
За это сообщение автора поблагодарили: S.Kuskov (2).
Старый 12.01.2012, 13:47   #2  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Интересно. Видимо второй (и последующие) вызов метода item() натыкается на какой-то мусор, оставшийся после первого вызова. А вызов info() каким-то образом подчищает этот мусор.

В качестве workaround могу предложить позиционироваться на ячейке при помощи метода offset:
X++:
static void checkExcell(Args _args)
{
    FilePath path='';
    container conFilter = ["Файл  (*.xls)", "*.xls"];
    SysExcelApplication exappl;
    SysExcelCells excells;
    SysExcelWorksheets exsheets;
    SysExcelWorksheet exsheet;
    SysExcelCell excell; // fix
    int row;
    real a,b;
    ;

    path = WinAPI::getOpenFileName(0,conFilter,"", "Укажите файл ",'',"");
    if (!path) return;

    exappl = SysExcelApplication::construct();
    exappl.workbooks().open(path);
    exsheets = exappl.workbooks().item(1).worksheets();
    exsheet = exsheets.itemFromNum(1);
    excells = exsheet.cells();
    excell = excells.item(1,1); // fix
    
    for(row = 1;row<3;row++)
    {
        //a = excells.item(row,1).value().double();
        a = excell.offset(row - 1, 0).value().double(); // fix
        
        //info(strfmt('%1',a));                          // строка 1
        
        //b = excells.item(row,2).value().double();
        b = excell.offset(row - 1, 1).value().double(); // fix
        
        info(strfmt('%1',a));                            // строка 2
        info(strfmt('%1',b));
    }

    exappl.quit();
}
За это сообщение автора поблагодарили: Logger (3), Димитрий (1).
Старый 12.01.2012, 13:54   #3  
Димитрий is offline
Димитрий
Участник
 
27 / 12 (1) ++
Регистрация: 10.08.2009
Да, действительно. Так заработало корректно.

Но, код подобного типа расскидан по системе, т.к. даже не думал, что можно в такое вляпаться. Честно скажу, что в большей степени бы порадовала заплатка на класс работы с Экселем.
Старый 12.01.2012, 14:03   #4  
Димитрий is offline
Димитрий
Участник
 
27 / 12 (1) ++
Регистрация: 10.08.2009
Да, так и получилось. На SysExcelCells

X++:
public SysExcelCell item(int _row, int _column, boolean first = false)
{
    if (first)
        return SysExcelCell::construct(version,COM::createFromVariant(cells.item(_row,_column)));
    else
    {
        if (!excell)
            excell = this.item(1,1,true); 
        return excell.offset(_row - 1, _column-1); 
    }
}
В декларации добавляем

SysExcelCell excell;

Работает.
Старый 12.01.2012, 14:31   #5  
Димитрий is offline
Димитрий
Участник
 
27 / 12 (1) ++
Регистрация: 10.08.2009
Но проблем при такой заплатке есть.

Если первая ячейка объединена с рядом стоящими, то работает неверно.
Старый 12.01.2012, 19:04   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Общее правило при работе с любыми внешними (по отношению к Axapta) объектами:

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

А в данном случае, нужно просто явно указать класс объекта, который будет выполнять обработку. В данном случае - чтение значение ячейки

X++:
static void checkExcell(Args _args)
{
    FilePath path='';
    container conFilter = ["Файл  (*.xls)", "*.xls"];
    SysExcelApplication exappl;
    SysExcelCells excells;
    SysExcelWorksheets exsheets;
    SysExcelWorksheet exsheet;
    int row;
    real a,b;

    // Добавчик
    SysExcelCell excellOne;
    SysExcelCell excellTwo;
    ;

    path = WinAPI::getOpenFileName(0,conFilter,"", "Укажите файл ",'',"");
    if (!path) return;

    exappl = SysExcelApplication::construct();
    exappl.workbooks().open(path);
    exsheets = exappl.workbooks().item(1).worksheets();
    exsheet = exsheets.itemFromNum(1);
    excells = exsheet.cells();

    for(row = 1;row<3;row++)
    {
        // Вот это надо сделать
        excellOne = excells.item(row,1);
        excellTwo = excells.item(row,2);
        
        a = excellOne.value().double();
        //info(strfmt('%1',a));                          // строка 1
        b = excellTwo.value().double();
        info(strfmt('%1',a));                            // строка 2
        info(strfmt('%1',b));
    }

    exappl.quit();

}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 12.01.2012, 20:51   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Общее правило при работе с любыми внешними (по отношению к Axapta) объектами:

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

А в данном случае, нужно просто явно указать класс объекта, который будет выполнять обработку. В данном случае - чтение значение ячейки
Интересно. Получается даже обёртка COM объекта в аксаптовский класс не отменяет это общее правило?
Старый 12.01.2012, 20:58   #8  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,654 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Думаю, что "обертка" не особо помогает при не явной инициализации промежуточных COM-объектов. Все "скрытые" COM-объекты - потенциальный источник проблем. Кто его знает как там с распределением памяти дела обстоят? Лучше уж потратить лишние переменные и иницилизировать все промежуточные COM-объекты явным образом.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Теги
excel

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Исследование скорости экспорта данных из Axapta в Excel (коллективный эксперимент) Gustav DAX: База знаний и проекты 79 13.02.2014 13:18
Sample Design Patterns: Microsoft Dynamics AX - Remedy for slow Microsoft Excel import Blog bot DAX Blogs 0 29.05.2011 17:13
Как изменить формат ячейки в EXCEL demon46 DAX: Программирование 21 27.01.2010 11:29
Чтение Excel-ячейки в Аксапте (2.5) через COM AKIS DAX: Программирование 3 25.03.2004 20:18
Ячейки Excel YVAS DAX: Программирование 2 05.08.2003 10:00

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 06:29.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.