AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 26.11.2004, 18:14   #1  
somebody is offline
somebody
Участник
 
128 / 30 (2) +++
Регистрация: 30.04.2003
Адрес: Москва
:( чтение из Excel текста, состоящего из цифр
Hello All!

Читаем текстовые ячейки из Excel, используя COM, примерно так:

class ... extends SysExcelImport
...
COM cell;
COM cellsOnSheet;
...
currentWorkSheet = this.openWorkSheet(curSheetNo); // метод класса SysExcelImport
cellsOnSheet = currentWorkSheet.cells(); //Gets all cells on sheet
cell = new COM();
cell = COM::createFromVariant(cellsOnSheet.item(rowNo, colNo));

Проблема возникает, если текст в ячейке состоит полностью из цифр. Cell.value() и cell.value2() для таких значений возвращают тип COMVariantType::VT_R8, т. е. число с плавающей точкой, и .bstr() даёт пустую строку. А хотелось бы получить COMVariantType::VT_BSTR. Присваивание типа не проходит, т. е.

cv.variantType(COMVariantType::VT_BSTR);
cv = cell.value();

не помогает.

Могу, конечно, брать .double(), делать num2str, убирать разделители тысяч и '.00'. Но не уверен, что это универсальный метод. Возможно, я просто что-то не так делаю.
Кто-нибудь сталкивался с подобной проблемой? Как заставить читать именно текст?
Старый 26.11.2004, 18:59   #2  
Petroff is offline
Petroff
Участник
Аватар для Petroff
 
33 / 10 (1) +
Регистрация: 14.11.2004
Адрес: Москва
Re: чтение из Excel текста, состоящего из цифр
Цитата:
Изначально опубликовано somebody
Hello All!

...

Могу, конечно, брать .double(), делать num2str, убирать разделители тысяч и '.00'. Но не уверен, что это универсальный метод. Возможно, я просто что-то не так делаю.
Кто-нибудь сталкивался с подобной проблемой? Как заставить читать именно текст?
Я делаю именно так, как вы сказали:

...
if (this.cellValue(comWorkSheet, x, y).variantType() == COMVariantType::VT_R8)
filed1 = num2str(this.cellValue(comWorkSheet, x, y).double(), 1, 0, 1, 0);
else
field1 = this.cellValue(comWorkSheet, x, y).bstr();
...

Разумеется, метод не совсем универсальный, но работает без проблем.
Старый 25.01.2013, 11:34   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Подниму тему.

Если значение ячейки состоит только из цифр, то почему-то после смены Excel'ем формата у ячейки с числового на текстовый, тип значения ячейки автоматически не преобразуется из COMVariantType::VT_R8 в COMVariantType::VT_BSTR.
Хотя визуально Excel начинает отображать это значение как текстовое: без дробной части и с выравниванием по левому краю! Правда без стандартного предупреждения в виде зелёненького уголочка "Число сохранено как текст". Если выполнить двойной щелчок по ячейке то такое предупреждение появится и тип значения сменится на COMVariantType::VT_BSTR.

При попытке программно прочитать такую ячейку возникает описанная ТС ситуация:
Цитата:
Сообщение от somebody Посмотреть сообщение
Проблема возникает, если текст в ячейке состоит полностью из цифр. Cell.value() и cell.value2() для таких значений возвращают тип COMVariantType::VT_R8, т. е. число с плавающей точкой, и .bstr() даёт пустую строку. А хотелось бы получить COMVariantType::VT_BSTR. Присваивание типа не проходит, т. е.

cv.variantType(COMVariantType::VT_BSTR);
cv = cell.value();

не помогает.
Может быть всё-таки есть какой-то способ програмно заставить ячейку обновить тип своего значения? А то преобразовывать double в строку, как-то не комильфо.
Старый 25.01.2013, 12:04   #4  
Andrux is offline
Andrux
Участник
Axapta Retail User
 
263 / 17 (1) ++
Регистрация: 29.05.2007
Сделайте в Excel замену в цифровых ячейках символа "." на символ "," (ctrl+H). Установите формат ячеек - Общий. И читайте по типам: bStr, double, int
Старый 25.01.2013, 12:08   #5  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Попробуйте принудительно "дернуть" значение ячейки после наложения на нее формата "Текстовый" (выражаюсь на VBA):

Range("A1").Value2 = "'" & Range("A1").Value2 (это известная операция добавление ведущего апострофа)

или так

Range("A1").Value2 = Range("A1").Value2 & "" (здесь просто пустая строка добавляется)

Во всяком случае, функция СУММ реагирует на такие изменения.

Ещё у ячейки есть свойство Range("A1").Text, но с ним надо осторожно, так как оно зависит от настроек отображения, например, от текущей ширины колонки.

Последний раз редактировалось Gustav; 25.01.2013 в 12:11.
За это сообщение автора поблагодарили: mazzy (2).
Старый 25.01.2013, 12:10   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Andrux Посмотреть сообщение
Сделайте в Excel замену в цифровых ячейках символа "." на символ "," (ctrl+H).
Не надо!
Если уж корежить исходник, то добавьте апостроф перед текстом.
В Экселе апостроф в самом начале строки означает, что дальше пойдет текст.

но лучше исходник не корежить.
Старый 25.01.2013, 12:11   #7  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Если значение ячейки состоит только из цифр, то почему-то после смены Excel'ем формата у ячейки с числового на текстовый, тип значения ячейки автоматически не преобразуется из COMVariantType::VT_R8 в COMVariantType::VT_BSTR. Может быть всё-таки есть какой-то способ програмно заставить ячейку обновить тип своего значения?
Ох уж эти импорты... Не сочтите за саморекламу, но я лично в подобных ситуациях использую класс для преобразования значений между различными значимыми типами - и без разницы, какой там в файле формат у ячейки...
Старый 25.01.2013, 12:14   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
у людей как правило проблемы возникают с расчетными и корреспондетскими счетами.

20 цифр ексель выдает как нормализованное число (с мантиссой и степенью). В этом случае преобразователь не спасает.

Спасает апостроф перед цифрами, если есть возможность править исходник.
Старый 25.01.2013, 12:16   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Andrux Посмотреть сообщение
Сделайте в Excel замену в цифровых ячейках символа "." на символ "," (ctrl+H). Установите формат ячеек - Общий. И читайте по типам: bStr, double, int
К сожалению смена формата ячейки на общий ведёт себя также как и описанная выше смена формата на текстовый, т.е. не даёт никаких результатов. Тип ячейки так и остаётся COMVariantType::VT_R8.

Последний раз редактировалось S.Kuskov; 25.01.2013 в 12:19.
Старый 25.01.2013, 12:19   #10  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Не сочтите за саморекламу, но я лично в подобных ситуациях использую класс для преобразования значений между различными значимыми типами - и без разницы, какой там в файле формат у ячейки...
Т.е. это то же самое преобразование Double в Str, только внутри вспомогательного класса?
Старый 25.01.2013, 12:42   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от mazzy Посмотреть сообщение
у людей как правило проблемы возникают с расчетными и корреспондетскими счетами. 20 цифр ексель выдает как нормализованное число (с мантиссой и степенью).
Выдает в качестве строки в COMVariant при чтении значения ячейки из кода или же в качестве того, что будет отображено для значения ячейки в самом Excel? Мы все еще про импорт говорим?..
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Т.е. это то же самое преобразование Double в Str, только внутри вспомогательного класса?
Если угодно, да, то же самое: на входе импорта получается неизвестно откуда взявшийся файл с неизвестно как отформатированными ячейками (к слову, откуда возникло предположение, что файл можно менять?), а на выходе - значение нужного мне типа. Соотв. слой абстракции реализован один раз и потом работает "без лишнего шума и пыли", и никто мне не парит мозг из-за того, что пользователям вздумалось числовые данные отформатировать как текст, или из-за того, что Excel в очередной раз не к месту отличился умом и сообразительностью, преобразовав текст в число.

Последний раз редактировалось gl00mie; 25.01.2013 в 12:48.
Старый 25.01.2013, 13:50   #12  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Gustav Посмотреть сообщение
Попробуйте принудительно "дернуть" значение ячейки после наложения на нее формата "Текстовый" (выражаюсь на VBA):

Range("A1").Value2 = "'" & Range("A1").Value2 (это известная операция добавление ведущего апострофа)

или так

Range("A1").Value2 = Range("A1").Value2 & "" (здесь просто пустая строка добавляется)
Если это делать на стороне аксапты, то получается что в качестве аргумента функции COM.Value2() я должен передать результат конкатенации его же значения с апострофом или пустой строкой, которое я и немогу получить. Замкнутый круг получается
"Чтобы продать что-нибудь ненужное, нужно сначала купить что-нибудь ненужное, а у нас денег нет"

Цитата:
Сообщение от Gustav Посмотреть сообщение
Ещё у ячейки есть свойство Range("A1").Text, но с ним надо осторожно, так как оно зависит от настроек отображения, например, от текущей ширины колонки.
К сожалению и это свойство не работает если фактически тип у ячейки значения COMVariantType::VT_R8

На самом деле непонятно откуда Excel берёт информацию о типе ячейки, потому что отображает он её корректно в текстовом виде, а хранит получается что как число
Старый 25.01.2013, 14:18   #13  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Если это делать на стороне аксапты, то получается что в качестве аргумента функции COM.Value2() я должен передать результат конкатенации его же значения с апострофом или пустой строкой, которое я и немогу получить. Замкнутый круг получается
Да, пожалуй... А попробуйте сделать это через MS Script Control ( Поговорим об MS Script Control ). Это получится так же, как и на VBA в самом Excel. И можно даже и саму строку получить уже как настоящую строку из Script Control'а.
Старый 25.01.2013, 16:40   #14  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
На самом деле непонятно откуда Excel берёт информацию о типе ячейки, потому что отображает он её корректно в текстовом виде, а хранит получается что как число
Там все хитро, но суть в том, что строковые значения хранятся в отдельной от ячеек области - Shared Strings. В самих же ячейках, при этом, сохраняется ссылка на значение в этой области (по факту - индекс в массиве строк)

Нестроковые значения хранятся непосредственно в ячейках и их тип определяется самими данными.

Когда меняется формат ячейки, значение в ней хранящееся не переносится в эту область, а остается в ячейке (по сути, меняется лишь отображение этих данных, что хорошо видно на примере дат).

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

PS
Для получения текстового значения ячейки независимо от типа хранимых в ней данных можно пользоваться функцией Text() вместо Value() или Value2()
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: Logger (10).
Старый 25.01.2013, 17:41   #15  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
про .Text()
Цитата:
Сообщение от AndyD Посмотреть сообщение
Для получения текстового значения ячейки независимо от типа хранимых в ней данных можно пользоваться функцией Text() вместо Value() или Value2()
Цитата:
Сообщение от Gustav Посмотреть сообщение
Ещё у ячейки есть свойство Range("A1").Text, но с ним надо осторожно, так как оно зависит от настроек отображения, например, от текущей ширины колонки.
http://www.excelworld.ru/forum/3-48-27402-16-1349248973
За это сообщение автора поблагодарили: mikki_messer (1).
Старый 25.01.2013, 20:28   #16  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2476 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Увеличить ширину колонки перед считыванием.
И нехай подавится
__________________
Axapta v.3.0 sp5 kr2
Теги
excel, импорт, импорт из excel

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Исследование скорости экспорта данных из Axapta в Excel (коллективный эксперимент) Gustav DAX: База знаний и проекты 79 13.02.2014 13:18
[Excel] - Несколько версий Excel на машине клиента Андре DAX: Программирование 11 07.08.2007 13:45
Вызов Item() для коллекций Excel Владимир Максимов DAX: Программирование 15 17.08.2006 19:47
Чтение ИЗ Excel (а не запись в него) Mechanizm DAX: Программирование 10 04.07.2004 11:50
Чтение Excel-ячейки в Аксапте (2.5) через COM AKIS DAX: Программирование 3 25.03.2004 20:18

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 08:38.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.