![]() |
#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? |
|
![]() |
#2 |
Участник
|
скорее всего во внешнем try catch вы используете транзакцию. не используйте работу с екселем внутри транзакции
|
|
![]() |
#3 |
Сенбернар
|
Цитата:
Ищется волшебный метод узнать у Excel-я, есть ли в нем такое имя (поле, Range) или его нет. Так, чтобы Excel при этом не упал. Пока я такого метода не нашел.
__________________
Best Regards, Roman Последний раз редактировалось RVS; 17.01.2013 в 17:53. |
|
![]() |
#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). |
![]() |
#5 |
Сенбернар
|
Цитата:
Пример : есть восемь дизайнов одного и того же документа. Накладной, СФ. Именованные диапазоны - простейшее решение для того, чтобы одним и тем же кодом распихать данные по любому из этих дизайнов (ИМХО). Кстати, желание проверить, есть имя в данном шаблоне или нет - из той же оперы, не все клиенты хотят видеть все данные, которые распихиваем.. Спасибо, завтра попробую )
__________________
Best Regards, Roman |
|
![]() |
#6 |
Участник
|
Цитата:
Сообщение от RVS
![]() Ну, даже и не знаю.. )
Пример : есть восемь дизайнов одного и того же документа. Накладной, СФ. Именованные диапазоны - простейшее решение для того, чтобы одним и тем же кодом распихать данные по любому из этих дизайнов (ИМХО). Кстати, желание проверить, есть имя в данном шаблоне или нет - из той же оперы, не все клиенты хотят видеть все данные, которые распихиваем.. ![]() Если имеем несколько дизайнов, то, как правило, дело вовсе не ограничивается банальным изменением положения той или иной надписи на листе. Обычно все-таки добавляются некие дополнительные объекты дизайна. Ну, и стоит ли из-за 2..3 общих объектов "городить огород" с именованными диапазонами? Кроме того, а как это все в коде оформляется-то? Очевидно, через макросы (#define). Ну и в чем проблема для каждого дизайна сделать свой набор макросов, только вместо имен диапазонов так прямо и писать адрес верхней левой ячейки? X++: #define.BookMark_Title('A1')
comRange = comApplication.range(#BookMark_Title);
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
![]() |
#7 |
Участник
|
2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
|
|
![]() |
#8 |
Участник
|
Цитата:
Сообщение от ice
![]() 2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
Вы опять забываете тот факт, что модификация отчетов крайне редко заключается всего-лишь в добавлении/удалении одной строчки/столбца. Обычно все гораздо сложнее. И модификация макроса - это крайне незначительная часть всех модификаций.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
![]() |
#9 |
Moderator
|
Цитата:
Сообщение от ice
![]() 2Владимир Максимов: с таким подходом редактировать шаблоны становится трудоемко, тк надо всякий раз перебивать макросы, чтоб ячейки не поехали
В любом шаблоне делаем два листа: один - собственно шаблон (раскрашенный и расфуфыренный), второй - служебный, обычный лист без всякого форматирования. На второй выводится одна единственная строка - например, при помощи CopyFromRecordset. Без всяких поисков именованных или неименованных диапазонов, обычно хаотично разбросанных по парадному шаблону. Вот. А на первом прописываете формулы на ячейки этой единственной строки второго листа. Перед самым показом пользователю для первого листа делаете копию всего используемого диапазона первого листа и специальную вставку "Только значения", чтобы зафиксировать значения формул. Второй лист больше не нужен, удаляем его. Всё это происходит втёмную, до visible = true. Соответственно, если вы позднее вносите изменения в дизайн парадного шаблона, добавляя/удаляя колонки/строки, то формулы в ячейках сами перенастраиваются (ну, собственно как и имена, созданные по Ctrl+F3). Кстати, передачу данных для не очень больших табличных частей тоже можно включать в эту единственную строку, выгружаемую из Аксапты. На эту тему уже бывали беседы на форуме: Копирование в Excel |
|
![]() |
#10 |
Сенбернар
|
Цитата:
Сообщение от Владимир Максимов
![]() Если имеем несколько дизайнов, то, как правило, дело вовсе не ограничивается банальным изменением положения той или иной надписи на листе. Обычно все-таки добавляются некие дополнительные объекты дизайна. Ну, и стоит ли из-за 2..3 общих объектов "городить огород" с именованными диапазонами?
Цитата:
А переписывать отчеты за MS я как-то не готов ![]()
__________________
Best Regards, Roman |
|
![]() |
#11 |
Участник
|
Цитата:
Скорость (а главное внезапность!) изменения шаблонов для печати налоговых и той же месячной декларации просто поражает воображение. И в основном это как раз добавление/перемещение одной ячейки/строчки. Только именованными ячейками и спасаемся. Собственно процентов 90 последних изменений даже без девелопера решались - просто перетягиванием имеющихся ячеек местами. Так что, как говорил Ржевский, - "случаи бывают разные".
__________________
If it ain't broke, take it apart and find out why (с) |
|
![]() |
#12 |
Участник
|
Alexanderis.ua
А Вас не удивлят сама постановка вопроса в данной теме? Если с именованными ячейками все так замечательно, то зачем вообще проверять факт их существования?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
![]() |
#13 |
Участник
|
Мы около трех лет назад написали машинку :
Опрашиваем шаблон Excel какие именованные ячейки есть. Потом алгорим выводит в данные ячейки нужные значения Имеем один универсальный алгоритм на любое количество отчетов. Это дало возможность не программерам каждый раз следить за отчетами, а самим пользователям корректировать шаблоны как им надо. Они просто ставят оговоренные метки в нужное место шаблона. Есть определенный алгоритм разделения меток шапки и табличной части. Для тех кто будет это использовать хочу предупредить, что есть однако одна неприятность при удаление именованных ячеек в шаблоне. Они не удаляются из списка ActiveWorkbook.Names и при опросе передаются в Axapta, но при выводе данных Axapta вываливается с ошибкой. На данный момент решили данную проблему созданием VBA макроса, обеспечивающего удаление "неправильных" именнованных ячеек из ActiveWorkbook.Names |
|
![]() |
#14 |
Administrator
|
Цитата:
Сообщение от grishin
![]() Имеем один универсальный алгоритм на любое количество отчетов.
Это дало возможность не программерам каждый раз следить за отчетами, а самим пользователям корректировать шаблоны как им надо. Они просто ставят оговоренные метки в нужное место шаблона. Есть определенный алгоритм разделения меток шапки и табличной части. Из плюсов такого подхода:
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 21.01.2013 в 18:02. |
|
![]() |
#15 |
Участник
|
Цитата:
![]() Я не говорил, что все замечательно. Моя мысль проста - иногда использование именованых ячеек оправдано. Просто небольшая контра к Вашей категоричности с примером из жизни. Вот еще один пример - оттуда же. С 16 декабря 2011 вид НН изменился. Добавились новые ячейки и перетасовался порядок. Старые НН нужно печатать в прошлом варианте. Сделали 2 шаблона и на всякий случай проверяем наличие ячеек - чтобы не плодить кучу условий на печати - если ячейка есть, то напечатается. Это к вопросу о "зачем вообще проверять".
__________________
If it ain't broke, take it apart and find out why (с) |
|
![]() |
#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(); }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
![]() |
#17 |
Участник
|
Цитата:
Изменения самой НН не радикальны. Только расположение в основном, форматирование какое-то. И старая версия (которая до сих пор одна) не меняется уже. В таких условиях городить иерархию классов или отдельные методы - просто не рационально. И я опять повторюсь - я с Вами не спорю. В общем случае нужно очень хорошо подумать, стоит ли применять именованные ячейки. Но категорически отказываться от них я считаю тоже не правильно. DIXI
__________________
If it ain't broke, take it apart and find out why (с) |
|