Excel &С++ - получение данных
От: morok Россия  
Дата: 30.03.05 11:23
Оценка:
Здраствуйте. Дело вот в чем. Необходимо Получить данные из работающего приложения Excel.

На Вход подаются:
Worksheet — объект(или ссылка) книги MS Excel
Name — имя в виде строки , заданное для одного или нескольких объектов Excel::Range, содержащих данные.

Конечно получить объект Excel::Name достаточно просто.

Excel::NamesPtr spNames = spTheWorkbook->Names;

Excel::NamePtr spTheName = spNames->Item(_variant_t("TestName"));


Проблема состоит в следующем этапе. Ну никак не получается получить эту самую коллекцию объектов Range, с которыми связано это имя (в коде выше "TestName").Точнее не работает вот что

Excel::RangePtr range = spTheName->GetRefersToRange();

Если имя указывает на один Range, то вроде бы все нормально, но вот если на несколько, то это уже проблема. Не выходит. А больно надо, так как данные как я понимаю можно достать только через Range.

Пожалуйста, подскажите что может быть здесь за причина и что можно предпринять. Может я чего не так делаю?

Заранее благодарен.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re: Excel &С++ - получение данных
От: Elena_ Россия  
Дата: 30.03.05 13:01
Оценка: 1 (1)
Здравствуйте, morok, Вы писали:

M>Проблема состоит в следующем этапе. Ну никак не получается получить эту самую коллекцию объектов Range, с которыми связано это имя (в коде выше "TestName").Точнее не работает вот что


M>
M>Excel::RangePtr range = spTheName->GetRefersToRange();
M>

M>Если имя указывает на один Range, то вроде бы все нормально, но вот если на несколько, то это уже проблема. Не выходит.

Да вроде это и на VBA так не работает, попробуйте проще, типа
RangePtr range = pXL->GetRange(_variant_t("TestName"));
Пользователь — друг программиста!
Re[2]: Excel &С++ - получение данных
От: morok Россия  
Дата: 31.03.05 06:25
Оценка:
Здравствуйте, Elena_, Вы писали:

E_>Да вроде это и на VBA так не работает, попробуйте проще, типа

E_>
E_>RangePtr range = pXL->GetRange(_variant_t("TestName"));
E_>


Да действительно помогло. Проблема решилась. Спасибо.

А вы немогли бы еще подсказать, почему не работает вот этот код:
NamePtr name = spTheWorkbook->GetNames()->Add();

//Пробовал делать вот так...
//NamesPtr names = spTheWorkbook->GetNames();
//NamePtr name = names->Add( _variant_t("TestName") );

//И вот так...
//NamePtr name = m_spExcelApp->GetNames()->Add( _variant_t("TestName") );


Генерируется исключение при вызове функции Add объекта Names — CXX0030: Error: expression cannot be evaluated

Опять же заранее спасибо
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Excel - опциональные параметры в expression.Add()
От: Elena_ Россия  
Дата: 31.03.05 07:09
Оценка: 1 (1)
#Имя: FAQ.office.excel.add.optional
Здравствуйте, morok, Вы писали:

M>почему не работает вот этот код:

M>
M>NamePtr name = spTheWorkbook->GetNames()->Add();

M>//Пробовал делать вот так...
M>//NamesPtr names = spTheWorkbook->GetNames();
M>//NamePtr name = names->Add( _variant_t("TestName") );

M>//И вот так...
M>//NamePtr name = m_spExcelApp->GetNames()->Add( _variant_t("TestName") );
M>


M>Генерируется исключение при вызове функции Add объекта Names — CXX0030: Error: expression cannot be evaluated


Хотя все параметры формально Optional, на самом деле при отсутствии одних из них должны быть заданы другие — по смыслу

Из справки по Excel

expression.Add(Name, RefersTo, Visible, MacroType, ShortcutKey, Category, NameLocal, RefersToLocal, CategoryLocal, RefersToR1C1, RefersToR1C1Local)

expression Required. An expression that returns a Names object.

Name Optional Variant. Required if NameLocal isn’t specified. The text to use as the name (in the language of the macro). Names cannot include spaces and cannot look like cell references.

RefersTo Optional Variant. Required unless one of the other RefersTo arguments is specified. Describes what the name refers to (in the language of the macro, using A1-style notation). Note Nothing is returned if the reference does not exist.
...


Понятно, что если добавляем имя, то как минимум должно быть указано само имя и то, на что оно указывает.

То есть должно работать, например,
spTheWorkbook->GetNames()->Add(_variant_t("AAA"), _variant_t("=Лист1!$A$1:$A$5"));
Пользователь — друг программиста!
Re[4]: Excel &С++ - получение данных
От: morok Россия  
Дата: 31.03.05 07:19
Оценка:
Здравствуйте, Elena_, Вы писали:

E_>То есть должно работать, например,

E_>
E_>spTheWorkbook->GetNames()->Add(_variant_t("AAA"), _variant_t("=Лист1!$A$1:$A$5"));
E_>


Да действительно, работает. Сколько раз убеждаюсь, что документацию надо читать ВНИМАТЕЛЬНО. Вот видел же это — видел, эх дурак. Спасибо большое.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[4]: Уж извините за назойливость
От: morok Россия  
Дата: 31.03.05 09:10
Оценка:
Я конечно понимаю, что наверное выгляжу глупо. Но если так, то уж пожалуйста ткните меня еще раз...

Вот код, который благодаря вам почти работает.


Excel::SheetsPtr spSheets = spTheWorkbook->GetSheets();
Excel::_WorksheetPtr spWorksheet = spSheets->GetItem(1);

//Получаем объединение 
RangePtr r1 = spWorksheet->GetRange( "A1:C2" );
RangePtr r2 = spWorksheet->GetRange( "D3:D8" );
RangePtr unionRange = m_spExcelApp->Union( r1, r2 );
                
                
//Добавляем новое имя , указывающее на созданное объединение, причем адрес получаем External
NamePtr name = spTheWorkbook->GetNames()->Add(
                   _variant_t("TestName"),
                   _variant_t( 
  unionRange->GetAddress( _variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) )
                             ) 
                                              ); 
//А вот при попытке получить этот объект с которым связано имя программа вылетает
//с неизвестным исключением при попытке вызова метода GetRange 
//ни один из представленных ниже вариантов не работает                
//NamePtr foundName = spTheWorkbook->GetNames()->Item( _bstr_t("TestName") );
//RangePtr foundRange = m_spExcelApp->GetRange( foundName->GetRefersTo() );
//or
//RangePtr foundRange = m_spExcelApp->GetRange( _variant_t("TestName") );
//or
RangePtr foundRange = spWorksheet->GetRange( _variant_t("TestName") );

//Это для теста
foundRange->GetInterior()->ColorIndex = 5;



Пробовал указать привязку имени разными способами, то есть
был и такой
unionRange->GetAddress( _variant_t(true), _variant_t(true),Excel::xlA1 )
unionRange->GetAddress( _variant_t(false), _variant_t(false),Excel::xlA1 )

и т.п.

Ну ничего не могу понять, да и в хэлпе по VBA толком про такие вещи ничего не написано.
Помогите, чем сможите.

Спасибо.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[5]: Уж извините за назойливость
От: morok Россия  
Дата: 31.03.05 12:11
Оценка:
Здравствуйте, morok, Вы писали:

M>Я конечно понимаю, что наверное выгляжу глупо. Но если так, то уж пожалуйста ткните меня еще раз...


M>Вот код, который благодаря вам почти работает.



M>
M>Excel::SheetsPtr spSheets = spTheWorkbook->GetSheets();
M>Excel::_WorksheetPtr spWorksheet = spSheets->GetItem(1);

M>//Получаем объединение 
M>RangePtr r1 = spWorksheet->GetRange( "A1:C2" );
M>RangePtr r2 = spWorksheet->GetRange( "D3:D8" );
M>RangePtr unionRange = m_spExcelApp->Union( r1, r2 );
                
                
M>//Добавляем новое имя , указывающее на созданное объединение, причем адрес получаем External
M>NamePtr name = spTheWorkbook->GetNames()->Add(
M>                   _variant_t("TestName"),
M>                   _variant_t( 
M>  unionRange->GetAddress( _variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) )
M>                             ) 
M>                                              ); 
M>//А вот при попытке получить этот объект с которым связано имя программа вылетает
M>//с неизвестным исключением при попытке вызова метода GetRange 
M>//ни один из представленных ниже вариантов не работает                
M>//NamePtr foundName = spTheWorkbook->GetNames()->Item( _bstr_t("TestName") );
M>//RangePtr foundRange = m_spExcelApp->GetRange( foundName->GetRefersTo() );
M>//or
M>//RangePtr foundRange = m_spExcelApp->GetRange( _variant_t("TestName") );
M>//or
M>RangePtr foundRange = spWorksheet->GetRange( _variant_t("TestName") );

M>//Это для теста
M>foundRange->GetInterior()->ColorIndex = 5;
M>



M>Пробовал указать привязку имени разными способами, то есть

M>был и такой
M>
M>unionRange->GetAddress( _variant_t(true), _variant_t(true),Excel::xlA1 )
M>unionRange->GetAddress( _variant_t(false), _variant_t(false),Excel::xlA1 )
M>

M>и т.п.

M>Ну ничего не могу понять, да и в хэлпе по VBA толком про такие вещи ничего не написано.

M>Помогите, чем сможите.

M>Спасибо.


Сам нашел причину.
Дело вот в чем. При вожу код на VBA


Dim newName As Name
Dim foundName As Name
Dim r As range
Dim r1 As range
Dim r2 As range
Dim ur As range
Dim wb As Workbook
Dim str As String

'Create two ranges and then union them
Set r1 = range("a1", "a2")
Set r2 = range("a1", "b2")
Set ur = Union(r1, r2)

'Create new Name object and bind it with the range union
Set newName = Application.Names.Add("TestName", ur.Address(True, True, xlA1, True))

'Get name object from the application
Set foundName = Application.Names.Item("TestName")

str = Replace(foundName.RefersTo, Chr(34), "")
'Get range from name
Set r = Application.range(str)

r.Interior.ColorIndex = 5


Дело в том, что значение строковой переменной ReferTo объекта Name содержит ссылку на адрес в виде, например:
"="[Книга1]Лист1!$A$1""

А для получения Range'a необходиом подставить строку вида
"=[Книга1]Лист1!$A$1"

Заметили различия?
Тот кто назвал язык VBA — языком кухарок был не прав.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[6]: Уж извините за назойливость
От: Elena_ Россия  
Дата: 31.03.05 18:54
Оценка: 1 (1)
Здравствуйте, morok, Вы писали:

M>Дело вот в чем. При вожу код на VBA


M>
M>'Create two ranges and then union them
M>Set r1 = range("a1", "a2")
M>Set r2 = range("a1", "b2")
M>Set ur = Union(r1, r2)

M>'Create new Name object and bind it with the range union
M>Set newName = Application.Names.Add("TestName", ur.Address(True, True, xlA1, True))

M>'Get name object from the application
M>Set foundName = Application.Names.Item("TestName")

M>str = Replace(foundName.RefersTo, Chr(34), "")
M>'Get range from name
M>Set r = Application.range(str)

M>r.Interior.ColorIndex = 5
M>


Можно, наверное, и так, но я бы сделала типа
    _bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
    _bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
    _bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
    NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
    RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );


потому что если устанавливать вручную имя для несвязанного диапазона, то лист повторяется для каждого диапазона, наверное, Excel'ю "так понятнее". Точка с запятой в Russian locale, в English — запятая, это можно через Internatonal узнавать в произвольном случае
Пользователь — друг программиста!
Re[7]: Уж извините за назойливость
От: morok Россия  
Дата: 01.04.05 04:13
Оценка:
Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, morok, Вы писали:


M>>Дело вот в чем. При вожу код на VBA


M>>
M>>'Create two ranges and then union them
M>>Set r1 = range("a1", "a2")
M>>Set r2 = range("a1", "b2")
M>>Set ur = Union(r1, r2)

M>>'Create new Name object and bind it with the range union
M>>Set newName = Application.Names.Add("TestName", ur.Address(True, True, xlA1, True))

M>>'Get name object from the application
M>>Set foundName = Application.Names.Item("TestName")

M>>str = Replace(foundName.RefersTo, Chr(34), "")
M>>'Get range from name
M>>Set r = Application.range(str)

M>>r.Interior.ColorIndex = 5
M>>


E_>Можно, наверное, и так, но я бы сделала типа

E_>
E_>    _bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
E_>    NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
E_>    RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );
E_>


E_>потому что если устанавливать вручную имя для несвязанного диапазона, то лист повторяется для каждого диапазона, наверное, Excel'ю "так понятнее". Точка с запятой в Russian locale, в English — запятая, это можно через Internatonal узнавать в произвольном случае


Все хорошо. Это идея хорошая

если устанавливать вручную имя для несвязанного диапазона, то лист повторяется для каждого диапазона, наверное, Excel'ю "так понятнее".

Но вот только проблема в том, что при создании нового имени необходимо чтобы оно было таким:
"="[Книга1]Лист1!$A$1:$B$1""
Причем наличие кавычек похоже является критическим. Я только что проверил. Приведенная вами конструкция не хочет работать.

_bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
_bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
_bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
//-------А Вот на этом месте и вылетает,но если получить строку таким образом, то все нормально
//_bstr_t sAddr = _bstr_t("=\"") + sAddr1 + _bstr_t(";") + sAddr2 + _bstr_t("\"");

NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
//------------------------------------------------------------------
RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[7]: Уж извините за назойливость
От: morok Россия  
Дата: 01.04.05 10:07
Оценка:
Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, morok, Вы писали:


M>>Дело вот в чем. При вожу код на VBA


M>>
M>>'Create two ranges and then union them
M>>Set r1 = range("a1", "a2")
M>>Set r2 = range("a1", "b2")
M>>Set ur = Union(r1, r2)

M>>'Create new Name object and bind it with the range union
M>>Set newName = Application.Names.Add("TestName", ur.Address(True, True, xlA1, True))

M>>'Get name object from the application
M>>Set foundName = Application.Names.Item("TestName")

M>>str = Replace(foundName.RefersTo, Chr(34), "")
M>>'Get range from name
M>>Set r = Application.range(str)

M>>r.Interior.ColorIndex = 5
M>>


E_>Можно, наверное, и так, но я бы сделала типа

E_>
E_>    _bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
E_>    NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
E_>    RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );
E_>


E_>потому что если устанавливать вручную имя для несвязанного диапазона, то лист повторяется для каждого диапазона, наверное, Excel'ю "так понятнее". Точка с запятой в Russian locale, в English — запятая, это можно через Internatonal узнавать в произвольном случае
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[7]: Уж извините за назойливость
От: morok Россия  
Дата: 01.04.05 10:24
Оценка:
А если быть еще точнее, то Будет еще одна ошибочка связанная с этими ненавистными кавычками.
_bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t
(true) );
_bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
_bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
//-------А Вот на этом месте и вылетает,но если получить строку таким образом, то все нормально
//_bstr_t sAddr = _bstr_t("=\"") + sAddr1 + _bstr_t(";") + sAddr2 + _bstr_t("\"");
//или 
//_bstr_t sAddr = sAddr1 + _bstr_t(";") + sAddr2;


NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
//------------------------------------------------------------------


Вот так почему-то тоже не работает,
RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );

не стал копаться, так как можно по-другому, и надо мне получать через имя
NamePtr foundName = pBook->GetNames()->Item("TestName");

RangePtr foundRange = pXL->GetRange(foundName.GetRefersTo());

Однако вышеприведенная строка тоже не будет работать по той же причине — из-за ковычек
То есть объект Name возвращает ссылку через RefersTo в виде
"="[Книга1]Лист1!$A$1:$A$3""
А для использования этой строки в получении Range'a необходимо передать строку в виде
"=[Книга1]Лист1!$A$1:$A$3"
или
"[Книга1]Лист1!$A$1:$A$3"
— символ " — обозначает строку

Вот такая вот ф...я выходит.
В общем достаточно неудобная вещь. Получается нельзя напрямую использовать результат одной функции(Name.RefersTo()) как аргумент другой функции(Application.GetRange(Name.RefersTo()), сначала необходимо результат преобразовать, а потом уже использовать. Мне кажется это какая-то недоработка компании MS. Хотя может я просто не в курсе чего-то.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[8]: Уж извините за назойливость
От: Elena_ Россия  
Дата: 01.04.05 20:51
Оценка:
Здравствуйте, morok, Вы писали:

M>В общем достаточно неудобная вещь. Получается нельзя напрямую использовать результат одной функции(Name.RefersTo()) как аргумент другой функции(Application.GetRange(Name.RefersTo()), сначала необходимо результат преобразовать, а потом уже использовать. Мне кажется это какая-то недоработка компании MS. Хотя может я просто не в курсе чего-то.


Мне надо еще немного посмотреть, но мне всегда казалось, что, например, проблемы на несвязанных диапазонах с RefersToRange возникают именно в Russian версии, именно из-за чехарды с разделителями диапазонов — , или ; Сейчас под рукой нет English версии, чтобы проверить, думаю, что в ней не должно быть проблем с несвязанными диапазонами?

Этот вариант я проверила на Excel XP — Russian — вроде бы работало, похоже, что зависит от версии Excel'я, где-то еще и кавычки всплывают
E_>    _bstr_t sAddr1 = r1->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr2 = r2->GetAddress(_variant_t(true), _variant_t(true),Excel::xlA1, _variant_t(true) );
E_>    _bstr_t sAddr = _bstr_t("=") + sAddr1 + _bstr_t(";") + sAddr2;
        
E_>    NamePtr name = pBook->GetNames()->Add(_variant_t("TestName"), sAddr);
E_>    RangePtr foundRange = pXL->GetRange( _variant_t("TestName") );


Вообще-то не замечала, что с кавычками тоже проблемы, надо покопать, с запятой и точкой с запятой точно все время вылезают коллизии. Недавно попадалось здесь
Автор: Леонид
Дата: 28.01.05
Пользователь — друг программиста!
Excel - история с кавычками
От: Elena_ Россия  
Дата: 02.04.05 06:26
Оценка: 12 (2)
#Имя: FAQ.msoffice.excel.inquotes
Здравствуйте, Elena_, Вы писали:

E_>Вообще-то не замечала, что с кавычками тоже проблемы


Наконец-то до меня дошло, что значит эта история с кавычками

Дело в том, что Excel позволяет создавать имена не только для диапазонов, но и для констант, например,
ThisWorkbook.Names.Add "PI", "=3.1415"

При этом имя PI не появится ни в списке имен слева от строки формул, ни в списке имен в диалоге Перейти (Правка->Перейти), оно будет только в общем списке имен (Вставка->Имя), так как оно не относится ни к какому диапазону, при этом его можно использовать в формулах, например,
=2*PI*10

Также можно создать имя и для строковой константы, например
ThisWorkbook.Names.Add "Developer", "=""Elena"""

Это имя Developer тоже не появится ни в списке имен слева от строки формул, ни не в списке имен в диалоге Перейти, так оно также не относится ни к какому диапазону, но его можно использовать в формулах типа
="Разработчик: " & Developer

Поэтому, когда Вы добавляете имя, заключая ссылку на диапазон в кавычки, типа
ThisWorkbook.Names.Add "Addr1", "=""Лист1!$D$17"""

то Вы фактически добавляете строковую константу, не имеющую отношения ни к какому диапазону, и просто по содержанию "похожую" на ссылку, а могло быть не "=""Лист1!$D$17""", а "=""Лист1!$ZZZZZ$177777""", и все бы прекрасно отработало
Чтобы убедиться в этом, попробуйте выбрать Правка->Перейти на листе Лист1 и посмотреть, позволяет ли имя, добавленное с кавычками, перейти к диапазону, на который оно вроде бы ссылается, а на самом деле это не ссылка, а просто текстовая константа, содержащая ссылку.

Естественно, чтобы получить диапазон, используя такое имя, нужно выполнить обратное преобразование, то есть константу преобразовать к ссылке, как раз то, о чем Вы говорили

M>Получается нельзя напрямую использовать результат одной функции(Name.RefersTo()) как аргумент другой функции(Application.GetRange(Name.RefersTo()), сначала необходимо результат преобразовать, а потом уже использовать.


Конечно, это не то, что должно быть

Когда же имя создается с использованием именно ссылки, а не строковой константы,
ThisWorkbook.Names.Add "Addr", "=Лист333!$D$17"

тогда оно появляется и в списке имен слева от строки формул, и в диалоге Перейти, и выбрав его, там или там, Вы сразу переходите к диапазону, соответственно, и в коде дополнительного преобразования не требуется

Если же, как я поняла, у Вас возникают проблемы именно с методом Add, когда Вы добавляете именно ссылку, а не строковую константу, попробуйте записать макрос при выполнении действия присвоения имени, и посмотрите, какой синтаксис требует Ваша версия Excel. Попробуйте выполнить этот макрос уже как макрос в Excel, а потом перенесите в С++. Как я уже говорила, у меня все проблемы бывают с вариациями запятых и точек с запятой
Пользователь — друг программиста!
Re[10]: Уж извините за назойливость
От: morok Россия  
Дата: 04.04.05 09:43
Оценка:
Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, Elena_, Вы писали:


E_>>Вообще-то не замечала, что с кавычками тоже проблемы


E_>Наконец-то до меня дошло, что значит эта история с кавычками


E_>Дело в том, что Excel позволяет создавать имена не только для диапазонов, но и для констант, например,

E_>
E_>ThisWorkbook.Names.Add "PI", "=3.1415"
E_>

E_>При этом имя PI не появится ни в списке имен слева от строки формул, ни в списке имен в диалоге Перейти (Правка->Перейти), оно будет только в общем списке имен (Вставка->Имя), так как оно не относится ни к какому диапазону, при этом его можно использовать в формулах, например,
E_>
E_>=2*PI*10
E_>

E_>Также можно создать имя и для строковой константы, например
E_>
E_>ThisWorkbook.Names.Add "Developer", "=""Elena"""
E_>

E_>Это имя Developer тоже не появится ни в списке имен слева от строки формул, ни не в списке имен в диалоге Перейти, так оно также не относится ни к какому диапазону, но его можно использовать в формулах типа
E_>
E_>="Разработчик: " & Developer
E_>

E_>Поэтому, когда Вы добавляете имя, заключая ссылку на диапазон в кавычки, типа
E_>
E_>ThisWorkbook.Names.Add "Addr1", "=""Лист1!$D$17"""
E_>

E_>то Вы фактически добавляете строковую константу, не имеющую отношения ни к какому диапазону, и просто по содержанию "похожую" на ссылку, а могло быть не "=""Лист1!$D$17""", а "=""Лист1!$ZZZZZ$177777""", и все бы прекрасно отработало
E_>Чтобы убедиться в этом, попробуйте выбрать Правка->Перейти на листе Лист1 и посмотреть, позволяет ли имя, добавленное с кавычками, перейти к диапазону, на который оно вроде бы ссылается, а на самом деле это не ссылка, а просто текстовая константа, содержащая ссылку.

E_>Естественно, чтобы получить диапазон, используя такое имя, нужно выполнить обратное преобразование, то есть константу преобразовать к ссылке, как раз то, о чем Вы говорили


M>>Получается нельзя напрямую использовать результат одной функции(Name.RefersTo()) как аргумент другой функции(Application.GetRange(Name.RefersTo()), сначала необходимо результат преобразовать, а потом уже использовать.


E_>Конечно, это не то, что должно быть


E_>Когда же имя создается с использованием именно ссылки, а не строковой константы,

E_>
E_>ThisWorkbook.Names.Add "Addr", "=Лист333!$D$17"
E_>

E_>тогда оно появляется и в списке имен слева от строки формул, и в диалоге Перейти, и выбрав его, там или там, Вы сразу переходите к диапазону, соответственно, и в коде дополнительного преобразования не требуется

E_>Если же, как я поняла, у Вас возникают проблемы именно с методом Add, когда Вы добавляете именно ссылку, а не строковую константу, попробуйте записать макрос при выполнении действия присвоения имени, и посмотрите, какой синтаксис требует Ваша версия Excel. Попробуйте выполнить этот макрос уже как макрос в Excel, а потом перенесите в С++. Как я уже говорила, у меня все проблемы бывают с вариациями запятых и точек с запятой


Да действительно так. Большое спасибо за помощь в данном вопросе.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re: Excel &С++ - получение данных
От: morok Россия  
Дата: 05.04.05 09:39
Оценка:
Здраствуйте, Elena_.

Вы как-то писали, что разделитель в записи вида
"=A1:A2,D2:D4"
зависит от локали. А немогли бы подсказать что это именно за разделитель. То есть разделитель элементов списка или что-то другое.

Потому как выражение вида
Application.Internation(xlListSeparator)

должно возвращать именно этот разделитель?

Заранее спасибо.
Лень — это не врожденное чувство советского человека, а средство борьбы с неуемной, но бестолковой энергией начальника...
Re[2]: Excel &С++ - получение данных
От: Elena_ Россия  
Дата: 05.04.05 21:15
Оценка:
Здравствуйте, morok, Вы писали:

M>Вы как-то писали, что разделитель в записи вида

M>"=A1:A2,D2:D4"
M>зависит от локали. А немогли бы подсказать что это именно за разделитель. То есть разделитель элементов списка или что-то другое.

M>Потому как выражение вида

M>
M>Application.Internation(xlListSeparator)
M>

M>должно возвращать именно этот разделитель?

Честно говоря, в документации я ни разу не встречала четкой формулировки по этому поводу, но вроде используют именно xlListSeparator в таких адресах, есть еще xlColumnSeparator и xlRowSeparator — это для массивов

В инете выложена такая книга TranslateIT.zip, там преобразуют всякие формулы в разные локализации Excel, там можно посмотреть, когда они используют xlListSeparator, а когда xlColumn и Row Separator, код в ней открыт
Пользователь — друг программиста!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.