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

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

===================================================

Попутный любопытствующий вопрос. Давно терзаюсь.

Класс ComExcelDocument_RU напичкан проверками, аналогичными тем, что приводит Roman777 в своем сообщении:

if (!XLSWorkSheet) throw error("@DIS6043");

Так уж ли они необходимы? Так уж ли часто эти _workSheet и _bookMark выходят из-под контроля?


P.S. Проверки в этом классе напоминают мне примерно следующую ситуацию:

Допустим, я иду по адресу внутри города:
- вот эта улица (document),
- вот этот дом (sheet),
- вот эта квартира (range),
- заношу палец над звонком в дверь...
И тут всплывает вопрос "А тот ли это город?!"


"Выдать WorkSheet! - А существует ли документ, его содержащий?!":
Код:
private COM getWorkSheet(anyType _workSheetID)
{
    COM  workSheets,
         comRet;
    ;
    if (m_comDocument)
    {
        try
        {
            workSheets = m_comDocument.worksheets();
            comRet     = workSheets.item(_workSheetID);
        }
        catch (Exception::Error)
        {
            throw error("@DIS6043");
        }
    }
    return comRet;
}
Или я чего-то принципиально не понимаю?

Последний раз редактировалось Gustav; 05.09.2006 в 09:58.
Старый 01.09.2006, 18:37   #2  
somebody is offline
somebody
Участник
 
128 / 30 (2) +++
Регистрация: 30.04.2003
Адрес: Москва
2 Gustav
IMHO эти проверки помогают:
1 (и главное). против ошибок собственно программистских...
2. против ошибок, связанных с версиями MS Office, неверно работающими с данной версией Аксапты (несертифицированных для данной версии Аксапты)...
Это по моему опыту.
Старый 01.09.2006, 21:57   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
somebody, спасибо за мнение, позволю себе немножко поразглагольствовать

Речь моя не о проверках вообще, а об их избыточном, как мне кажется, количестве именно в классе ComExcelDocument_RU.
Начну со второго тезиса:
Цитата:
Сообщение от somebody
2. против ошибок, связанных с версиями MS Office, неверно работающими с данной версией Аксапты (несертифицированных для данной версии Аксапты)
Я знаю только одну подобную проблему - c Value и Value2 при переходе от Excel 2000 к Excel XP. Причем, класс ComExcelDocument_RU использует безопасное Value2, ничего при этом как раз не проверяя. Существуют ли еще какие-то примеры подобного рода "борьбы" с версиями Office?
Цитата:
Сообщение от somebody
1 (и главное). против ошибок собственно программистских...
Ну, какого рода могут быть ТАКИЕ ошибки при спуске по простой иерархии Excel: Application - Workbook - Worksheet - Range у программиста в здравом уме и светлой памяти? Если он полезет в Range, не получив сначала ссылки на один из вышестоящих объектов, то это отловится на этапе отладки и он это поправит. Он наверняка знает, что если задаст номер строки больше, чем 65536, то тоже получит ошибку. Но речь-то о проверках существования объектов вроде "if (!m_comApplication)", а не "if (row > 65536)". Именно эти проверки я не понимаю...

Давайте посмотрим для иллюстрации "первозданную" (со слоя dis) реализацию метода findRange:
Код:
// Creates object range type named the same way as Excel bookmark
// bookMark -> Excel bookmark name
protected COM findRange(MSOfficeBookMark_RU bookMark, int _workSheet = 1)
{
    COM comRange,
        comWorkSheet;
    COM comApplication;
    ;
    if (m_comDocument)
    {
        comWorkSheet   = this.getWorkSheet(_workSheet);
        comApplication = m_comDocument.application();
        comWorkSheet.activate();
        if (comWorkSheet && comApplication)
        {
            comRange = comApplication.range(bookMark);
        }
    }
    return comRange;
}
Извините уж, немножко "оторвусь"

Первое "идеологическое" замечание: что это за "Excel bookmark" такой, по которому находится объект Range? По смыслу это адрес ячейки вида "А1" или имя именованного диапазона, создаваемое, например, командой "Вставка-Имя-Присвоить" - также в виде строки вида "МояЯчейка" или "МойДиапазон". Но в большинстве случаев это именно адрес вида "А1", или "F19", или "IV65536" и т.п. Так почему не назвать просто и "по-родному по-эксельному" - Address?

Посмотрим, кстати, в AOT, что это за EDT такой навороченный - MSOfficeBookMark_RU. Находим: стринг 80 символов, Label - "Закладка", HelpText - "Введите название закладки, в которую будут эскпортироваться данные"... Уф-уф-уф... Вместо того, чтобы выходить из чащи, мы в нее еще глубже прёмся... Почему не использовать обычный тип "str"? Где мы еще хотим использовать этот MSOfficeBookMark_RU? В Ворде, да. Оттуда эта "закладка", похоже и пришла. Так пусть там и будет "закладка", а в Ёкселе будет "адрес" и оба будут типа "str"! А где еще использовать-то этот тип, кроме как в Ворде и Экселе? Или мы хотим от этого типа в дальнейшем порождать какое-то бешенное потомство? Так предок уже сам не совсем нормальный, получается... Какое потомство-то?

Я вам честно говорю, когда я, в Excel'е за 10 лет кое-что уже разумеющий, начал изучение этого класса и набрёл на этот метод, то просто съёжился: "range" - интуитивно понятно, "worksheet" - тоже, но что такое в этой связке "bookMark" с типом "MSOfficeBookMark_RU"? ооой...

Далее - "документ". В Ворде это "Document", согласен. Но в Экселе-то - "Workbook"! Зачем привычную иерархию "Application - Workbook - Worksheet - Range" менять на "Application - Document - Worksheet - Range"? Цель какая? Сбить с толку человека, знакомого с Excel ранее? Вполне получается.

Или все силы брошены на поддержку наследования с гордым предком ("родителем") ComOfficeDocument_RU и двумя послушными потомками ("детьми") ComExcelDocument_RU и ComWordDocument_RU? Мы собираемся создавать еще "внуков"? Интересно, как они примерно могут называться: "Эксель Экселей" или "Ворд Вордов"? А "родителя" мы создали только потому, что у "детей" есть похожие операции типа "OpenFile" или "QuitApplication"?

Уф, в запальчивости устал. Прервусь пока.
(to be continued later...)
Старый 04.09.2006, 15:41   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,711 / 1201 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Не так давно мне пришлось перелопачивать классы-наследники от ComExcelDocument_RU. Это были классы, работающие с ActiveX-компонентом OWC-SpreadSheet. И это были именно наследники, поскольку многие методы одни-в-один применимы как к собственно Excel, так и к этим компонентам.

Однако с ними оказалась следующая проблема. Самый первый выпущенный ActiveX компонент относился к версии Office 2000. Т.е. к 9 версии (m_Application.version()). Так вот, в старших версиях из поставки Office XP (10 версия) и Office 2003 (11 версия) оказалось что:

Значение Borders.LineStyle принимают значение из другого нумератора. Проще говоря, имеют другие допустимые значения.

Горизонтальное и вертикальное выравнивание осуществляется другими методами. Вообще другими.

Может, есть еще какие отличия, но пока не всплыли.

С другой стороны, у нас установлена версия AXAPTA 2.5. По умолчанию, в ней не предусмотрена возможность экспорта отчетов в Excel. Однако ребята из Columbus-а сумели "прикрутить" механизм такого экспорта передрав его из 3.0 Для этого они сделали еще один класс наследник (правда, напрямую от ComOfficeDocument_RU, что лично мне кажется странным).

Хотя, согласен, проверки на факт существования ссылки в m_comApplication явно лишние. Лишние не потому, что такого не может быть (еще как может!), а потому, что эти проверки не выдают никаких сообщений об ошибках! Т.е. отчет просто не выполняется, а почему - непонятно.

Если бы подобных проверок не было, то программист получил бы исключение и быстро нашел место ошибки. Хотя, в классе-родителе, в большинстве случаев, такое сообщение все-таки есть! А это уже явная подсказка разработчику "где копать". Где он ошибся.

Насчет именования.

Как Вы себе представляете перекрытие имени переменной в классе-наследнике? Т.е. если в классе-родителе переменная была названа m_comDocument, то извольте именно так к ней и обращаться в классе-потомке или создавайте новую переменную. Но в этом случае необходимо будет перекрыть вообще все методы класса-родителя. И зачем в этом случае родитель?

Ах, да, Вы не видите зачем нужен класс-родитель. Ну, так опять же недавно я делал запись служебной информации в созданный файл. Т.е. кто и когда этот файл (отчет) создал. Так вот, и для Word, и для Excel это делается совершенно одинаковыми методами. Буквально. Т.е. это явно имеет смысл выделить в класс-родитель.

То же самое относится и к BookMark. Вы смотрели методы класса ComWordApplication()? Как ни странно, в нем есть методы FindRange и InsertValue.
Старый 04.09.2006, 15:47   #5  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
в продолжение оффтопа...
Цитата:
Сообщение от Gustav
P.S. Проверки в этом классе напоминают мне примерно следующую ситуацию:

Допустим, я иду по адресу внутри города:
- вот эта улица (document),
- вот этот дом (sheet),
- вот эта квартира (range),
- заношу палец над звонком в дверь...
И тут всплывает вопрос "А тот ли это город?!"
Вот один товарищ не задался этим вопросом... Подробнее см. в х/ф "Ирония судьбы или с легким паром"

А что касается проверок... ИМХО, это один из признаков хорошего тона - типа "семь раз отмерь". Согласен, можно, конечно, найти в данном конкретном случае избыточность, но наличие привычки все перепроверять само по себе не лишнее...

Расскажу страшилку в тему Лично я, будучи еще зеленым студентом, из-за отсутствия этой привычки провалил тестовое задание при трудоустройстве в солидную контору Как сейчас помню - сгенерил (в смысле new) некий объект, проверил его сразу же на != null и передал указатель в метод. А в теле метода сразу стал обращаться к объекту, как заведомо существующему.
Проверяющий мою работу программист назвал это грубой ошибкой (кстати, спасибо ему за это). С тех пор стараюсь следовать правилу "если что-то пришло извне, сначала проверь, потом используй"
__________________
Старый 05.09.2006, 18:33   #6  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
в методе
\Classes\ComWordDocument_RU\FindField

есть такие строки:

Код:
            if (substr(m_comApplication.version(), 1 ,1) >= '9') // Word 2000 and later
            {
                field = fields.item(_bookMark);
            }
            else
            {
                   ,,,
            }
проверка на то что версия офиса начинается с символа большего либо равного 9ти
у меня например версия "10.0" условие не выполняется и работает код предназначенный для более старых версий соответственно более медленный )
Теги
best practice, spreadsheet, как правильно, стиль программирования

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
args в классе от RunBase Zoe DAX: Программирование 5 11.12.2008 18:20
Баг (?) в классе LedgerBalanceDim Peter Savintsev DAX: Программирование 3 18.06.2008 05:41
Кэш в классе Specification Hyper DAX: Программирование 0 12.04.2008 18:52
Как в наследуемом классе кл. RunBase перехватывать модиф. полей м.Prompt() alef_nor DAX: Программирование 2 11.05.2006 15:07
как обратиться в классе к тек.записи? sev DAX: Программирование 20 02.08.2005 11:05
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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