17.01.2013, 17:03 | #1 |
Участник
|
Excel - проверить существование Range
- если в шаблоне Excel есть range с именем "zzz", записать туда значение.
- если такого range в шаблоне нет - не записывать туда ничего, и при этом не падать (!) Пробую решать : X++: public void insertValueSafeMode(Bookmark _bookmark, anytype _anyVal, int _workSheet = 1, NoYes _diagnostics = NoYes::No) { COM comApplication; COM comWorkSheet; COM comRange; int curInfoLine; if (! m_comDocument) throw error(strfmt("@GEE6401", this.getApplicationName())); try { curInfoLine = infolog.line(); comWorkSheet = this.getWorkSheet(_workSheet); comApplication = m_comDocument.application(); comWorkSheet.activate(); if (comWorkSheet && comApplication) { comRange = comApplication.range(_bookMark); } if (comRange) { this.insertValueInRange(comRange, _anyVal); } } catch { infolog.clear(curInfoLine); if (_diagnostics) { setPrefix('Отсутствует поле в шаблоне Excel'); warning(strfmt('insertValueSafeMode(%1, %2, %3) failed', _bookmark, _anyVal, _workSheet)); } } } Any idea? |
|
17.01.2013, 17:11 | #2 |
Участник
|
скорее всего во внешнем try catch вы используете транзакцию. не используйте работу с екселем внутри транзакции
|
|
17.01.2013, 17:45 | #3 |
Сенбернар
|
Цитата:
Ищется волшебный метод узнать у Excel-я, есть ли в нем такое имя (поле, Range) или его нет. Так, чтобы Excel при этом не упал. Пока я такого метода не нашел.
__________________
Best Regards, Roman Последний раз редактировалось RVS; 17.01.2013 в 17:53. |
|
17.01.2013, 18:04 | #4 |
Участник
|
Способы есть. Причем не один
X++: static void Job_Excel_ExistsRange(Args _args) { COMExcelDocument_RU excel; MSOfficeBookMark_RU bookMark = 'test3'; // Имя, которое ищем COM comWorkSheet; COM comNames; COM comName; int totalI; int nextI; str strName; str strSearh; COM comApplication; COM comRange; boolean existsRange = false; str strRange; ; excel = new ComExcelDocument_RU(); excel.newFile('',true); excel.visible(true); comWorkSheet = excel.getWorkSheet(1); comNames = comWorkSheet.Names(); // Для тестирования создаю именованные диапазоны comNames.add('test1','=$A$1'); comNames.add('test2','=$A$2'); // comNames.add('test3','=$A$3'); // Вариант 1 - перебор существующих имен для поиска совпадений /* Коллекция Names есть на всех 3 уровнях: Application, WorkBook, WorkSheet Можно использовать перебор по любой коллекции Возвращаемое из коллекции имя предваряется именем листа, поэтому надо дополнить искомое имя диапазона именем листа с восклицательным знаком */ totalI = comNames.Count(); strSearh = comWorkSheet.Name() + '!' + bookMark; for (nextI = 1; nextI <= totalI; nextI++) { comName = comNames.Item(nextI); strName = comName.Name(); if (strName == strSearh) { existsRange = true; break; } // if (strName == strSearh) } // for (nextI = 1; nextI <= totalI; nextI++) if (existsRange) { info('Вариант 1: ' + bookMark + ' - найден'); } // Вариант 2 - "макроподстановка" existsRange = false; comApplication = comWorkSheet.application(); // m_comDocument.application(); // Ошибка в Range генерит сообщение об ошибке, которое не подавляется Try...Catch // comRange = comApplication.range(bookMark); // Поэтому использую "макроподстановку" Evaluate comRange = comApplication.evaluate(bookMark); // В объекте comRange нет метода Error(), поэтому штатно прочитать ошибку не получается // Конвертирую объект в строку и ищу в нем ключевое слово "ERROR" strRange = comRange.toString(); if (strScan(strRange,'ERROR',1,strLen(strRange)) == 0) { existsRange = true; } if (existsRange) { info('Вариант 2: ' + bookMark + ' - найден'); } if (! existsRange) { info(bookMark + ' - не существует'); } } Только вот, сам факт использования именованных диапазонов особого смысла не имеет. Больно уж специфические способы модификации файла Excel требуются, чтобы использование именованных диапазонов было оправдано. В общем случае - это просто бессмысленно. PS: Иногда возвращаемое имя диапазона из коллекции Names() может и не предваряться именем листа. В каких случаях имя листа указывается, а в каких - нет лично я не понял
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... Последний раз редактировалось Владимир Максимов; 17.01.2013 в 18:14. |
|
|
За это сообщение автора поблагодарили: RVS (3), Polgid (1). |
17.01.2013, 20:12 | #5 |
Сенбернар
|
Цитата:
Пример : есть восемь дизайнов одного и того же документа. Накладной, СФ. Именованные диапазоны - простейшее решение для того, чтобы одним и тем же кодом распихать данные по любому из этих дизайнов (ИМХО). Кстати, желание проверить, есть имя в данном шаблоне или нет - из той же оперы, не все клиенты хотят видеть все данные, которые распихиваем.. Спасибо, завтра попробую )
__________________
Best Regards, Roman |
|
18.01.2013, 14:31 | #6 |
Участник
|
Цитата:
Сообщение от RVS
Ну, даже и не знаю.. )
Пример : есть восемь дизайнов одного и того же документа. Накладной, СФ. Именованные диапазоны - простейшее решение для того, чтобы одним и тем же кодом распихать данные по любому из этих дизайнов (ИМХО). Кстати, желание проверить, есть имя в данном шаблоне или нет - из той же оперы, не все клиенты хотят видеть все данные, которые распихиваем.. Если имеем несколько дизайнов, то, как правило, дело вовсе не ограничивается банальным изменением положения той или иной надписи на листе. Обычно все-таки добавляются некие дополнительные объекты дизайна. Ну, и стоит ли из-за 2..3 общих объектов "городить огород" с именованными диапазонами? Кроме того, а как это все в коде оформляется-то? Очевидно, через макросы (#define). Ну и в чем проблема для каждого дизайна сделать свой набор макросов, только вместо имен диапазонов так прямо и писать адрес верхней левой ячейки? X++: #define.BookMark_Title('A1')
comRange = comApplication.range(#BookMark_Title);
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
18.01.2013, 14:50 | #7 |
Участник
|
2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
|
|
18.01.2013, 15:09 | #8 |
Участник
|
Цитата:
Сообщение от ice
2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
Вы опять забываете тот факт, что модификация отчетов крайне редко заключается всего-лишь в добавлении/удалении одной строчки/столбца. Обычно все гораздо сложнее. И модификация макроса - это крайне незначительная часть всех модификаций.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
18.01.2013, 17:04 | #9 |
Moderator
|
Цитата:
Сообщение от ice
2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
В любом шаблоне делаем два листа: один - собственно шаблон (раскрашенный и расфуфыренный), второй - служебный, обычный лист без всякого форматирования. На второй выводится одна единственная строка - например, при помощи CopyFromRecordset. Без всяких поисков именованных или неименованных диапазонов, обычно хаотично разбросанных по парадному шаблону. Вот. А на первом прописываете формулы на ячейки этой единственной строки второго листа. Перед самым показом пользователю для первого листа делаете копию всего используемого диапазона первого листа и специальную вставку "Только значения", чтобы зафиксировать значения формул. Второй лист больше не нужен, удаляем его. Всё это происходит втёмную, до visible = true. Соответственно, если вы позднее вносите изменения в дизайн парадного шаблона, добавляя/удаляя колонки/строки, то формулы в ячейках сами перенастраиваются (ну, собственно как и имена, созданные по Ctrl+F3). Кстати, передачу данных для не очень больших табличных частей тоже можно включать в эту единственную строку, выгружаемую из Аксапты. На эту тему уже бывали беседы на форуме: Копирование в Excel |
|
18.01.2013, 17:59 | #10 |
Сенбернар
|
Цитата:
Сообщение от Владимир Максимов
Если имеем несколько дизайнов, то, как правило, дело вовсе не ограничивается банальным изменением положения той или иной надписи на листе. Обычно все-таки добавляются некие дополнительные объекты дизайна. Ну, и стоит ли из-за 2..3 общих объектов "городить огород" с именованными диапазонами?
Цитата:
А переписывать отчеты за MS я как-то не готов
__________________
Best Regards, Roman |
|
20.01.2013, 17:39 | #11 |
Участник
|
Цитата:
Скорость (а главное внезапность!) изменения шаблонов для печати налоговых и той же месячной декларации просто поражает воображение. И в основном это как раз добавление/перемещение одной ячейки/строчки. Только именованными ячейками и спасаемся. Собственно процентов 90 последних изменений даже без девелопера решались - просто перетягиванием имеющихся ячеек местами. Так что, как говорил Ржевский, - "случаи бывают разные".
__________________
If it ain't broke, take it apart and find out why (с) |
|
21.01.2013, 12:57 | #12 |
Участник
|
Alexanderis.ua
А Вас не удивлят сама постановка вопроса в данной теме? Если с именованными ячейками все так замечательно, то зачем вообще проверять факт их существования?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
21.01.2013, 16:02 | #13 |
Участник
|
Мы около трех лет назад написали машинку :
Опрашиваем шаблон Excel какие именованные ячейки есть. Потом алгорим выводит в данные ячейки нужные значения Имеем один универсальный алгоритм на любое количество отчетов. Это дало возможность не программерам каждый раз следить за отчетами, а самим пользователям корректировать шаблоны как им надо. Они просто ставят оговоренные метки в нужное место шаблона. Есть определенный алгоритм разделения меток шапки и табличной части. Для тех кто будет это использовать хочу предупредить, что есть однако одна неприятность при удаление именованных ячеек в шаблоне. Они не удаляются из списка ActiveWorkbook.Names и при опросе передаются в Axapta, но при выводе данных Axapta вываливается с ошибкой. На данный момент решили данную проблему созданием VBA макроса, обеспечивающего удаление "неправильных" именнованных ячеек из ActiveWorkbook.Names |
|
21.01.2013, 17:57 | #14 |
Administrator
|
Цитата:
Сообщение от grishin
Имеем один универсальный алгоритм на любое количество отчетов.
Это дало возможность не программерам каждый раз следить за отчетами, а самим пользователям корректировать шаблоны как им надо. Они просто ставят оговоренные метки в нужное место шаблона. Есть определенный алгоритм разделения меток шапки и табличной части. Из плюсов такого подхода:
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 21.01.2013 в 18:02. |
|
22.01.2013, 05:26 | #15 |
Участник
|
Цитата:
Я не говорил, что все замечательно. Моя мысль проста - иногда использование именованых ячеек оправдано. Просто небольшая контра к Вашей категоричности с примером из жизни. Вот еще один пример - оттуда же. С 16 декабря 2011 вид НН изменился. Добавились новые ячейки и перетасовался порядок. Старые НН нужно печатать в прошлом варианте. Сделали 2 шаблона и на всякий случай проверяем наличие ячеек - чтобы не плодить кучу условий на печати - если ячейка есть, то напечатается. Это к вопросу о "зачем вообще проверять".
__________________
If it ain't broke, take it apart and find out why (с) |
|
22.01.2013, 16:28 | #16 |
Участник
|
Цитата:
Цитата:
Сообщение от Alexanderis.ua
Вот еще один пример - оттуда же. С 16 декабря 2011 вид НН изменился. Добавились новые ячейки и перетасовался порядок. Старые НН нужно печатать в прошлом варианте.
Сделали 2 шаблона и на всякий случай проверяем наличие ячеек - чтобы не плодить кучу условий на печати - если ячейка есть, то напечатается. Это к вопросу о "зачем вообще проверять". X++: if ( <= ...) { val1 = ...; Range1.Value(val1); } else { val2 = ...; Range2.Value(val2); } X++: val1 = ...; Range1.Value(val1); val2 = ...; Range2.Value(val2); Ну, пока значение, записываемое в ячейку - простое и общее количество ячеек - небольшое, это еще работает. Но с увеличением количества версий Вы сильно задумаетесь хотя бы об отдельных методах для заполнения каждого шаблона. В перспективе - иерархии классов. Нечто вроде X++: if ( <= ...) { this.Method1(); } else { this.Method2(); }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
22.01.2013, 16:53 | #17 |
Участник
|
Цитата:
Изменения самой НН не радикальны. Только расположение в основном, форматирование какое-то. И старая версия (которая до сих пор одна) не меняется уже. В таких условиях городить иерархию классов или отдельные методы - просто не рационально. И я опять повторюсь - я с Вами не спорю. В общем случае нужно очень хорошо подумать, стоит ли применять именованные ячейки. Но категорически отказываться от них я считаю тоже не правильно. DIXI
__________________
If it ain't broke, take it apart and find out why (с) |
|