![]() |
#1 |
Moderator
|
(ветка выделена отсюда 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. |
|
![]() |
#2 |
Участник
|
2 Gustav
IMHO эти проверки помогают: 1 (и главное). против ошибок собственно программистских... 2. против ошибок, связанных с версиями MS Office, неверно работающими с данной версией Аксапты (несертифицированных для данной версии Аксапты)... Это по моему опыту. |
|
![]() |
#3 |
Moderator
|
somebody, спасибо за мнение, позволю себе немножко поразглагольствовать
![]() Речь моя не о проверках вообще, а об их избыточном, как мне кажется, количестве именно в классе ComExcelDocument_RU. Начну со второго тезиса: Цитата:
Сообщение от somebody
2. против ошибок, связанных с версиями MS Office, неверно работающими с данной версией Аксапты (несертифицированных для данной версии Аксапты)
Цитата:
Сообщение от somebody
1 (и главное). против ошибок собственно программистских...
Давайте посмотрим для иллюстрации "первозданную" (со слоя 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...) |
|
![]() |
#4 |
Участник
|
Не так давно мне пришлось перелопачивать классы-наследники от 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. |
|
![]() |
#5 |
Дмитрий Ерин
|
в продолжение оффтопа...
Цитата:
Сообщение от Gustav
P.S. Проверки в этом классе напоминают мне примерно следующую ситуацию:
Допустим, я иду по адресу внутри города: - вот эта улица (document), - вот этот дом (sheet), - вот эта квартира (range), - заношу палец над звонком в дверь... И тут всплывает вопрос "А тот ли это город?!" ![]() А что касается проверок... ИМХО, это один из признаков хорошего тона - типа "семь раз отмерь". Согласен, можно, конечно, найти в данном конкретном случае избыточность, но наличие привычки все перепроверять само по себе не лишнее... Расскажу страшилку в тему ![]() ![]() Проверяющий мою работу программист назвал это грубой ошибкой (кстати, спасибо ему за это). С тех пор стараюсь следовать правилу "если что-то пришло извне, сначала проверь, потом используй" ![]()
__________________
![]() |
|
![]() |
#6 |
Участник
|
в методе
\Classes\ComWordDocument_RU\FindField есть такие строки: Код: if (substr(m_comApplication.version(), 1 ,1) >= '9') // Word 2000 and later { field = fields.item(_bookMark); } else { ,,, } у меня например версия "10.0" условие не выполняется и работает код предназначенный для более старых версий соответственно более медленный ![]() |
|
Теги |
best practice, spreadsheet, как правильно, стиль программирования |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|