Показать сообщение отдельно
Старый 17.01.2013, 18:04   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,711 / 1201 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Способы есть. Причем не один

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).