26.11.2004, 18:14 | #1 |
Участник
|
чтение из 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 |
Участник
|
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 |
Участник
|
Подниму тему.
Если значение ячейки состоит только из цифр, то почему-то после смены 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(); не помогает. |
|
25.01.2013, 12:04 | #4 |
Участник
|
Сделайте в Excel замену в цифровых ячейках символа "." на символ "," (ctrl+H). Установите формат ячеек - Общий. И читайте по типам: bStr, double, int
|
|
25.01.2013, 12:08 | #5 |
Moderator
|
Попробуйте принудительно "дернуть" значение ячейки после наложения на нее формата "Текстовый" (выражаюсь на 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 |
Участник
|
|
|
25.01.2013, 12:11 | #7 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Если значение ячейки состоит только из цифр, то почему-то после смены Excel'ем формата у ячейки с числового на текстовый, тип значения ячейки автоматически не преобразуется из COMVariantType::VT_R8 в COMVariantType::VT_BSTR. Может быть всё-таки есть какой-то способ програмно заставить ячейку обновить тип своего значения?
|
|
25.01.2013, 12:14 | #8 |
Участник
|
|
|
25.01.2013, 12:16 | #9 |
Участник
|
К сожалению смена формата ячейки на общий ведёт себя также как и описанная выше смена формата на текстовый, т.е. не даёт никаких результатов. Тип ячейки так и остаётся COMVariantType::VT_R8.
Последний раз редактировалось S.Kuskov; 25.01.2013 в 12:19. |
|
25.01.2013, 12:19 | #10 |
Участник
|
Цитата:
Сообщение от gl00mie
Не сочтите за саморекламу, но я лично в подобных ситуациях использую класс для преобразования значений между различными значимыми типами - и без разницы, какой там в файле формат у ячейки...
|
|
25.01.2013, 12:42 | #11 |
Участник
|
Цитата:
Если угодно, да, то же самое: на входе импорта получается неизвестно откуда взявшийся файл с неизвестно как отформатированными ячейками (к слову, откуда возникло предположение, что файл можно менять?), а на выходе - значение нужного мне типа. Соотв. слой абстракции реализован один раз и потом работает "без лишнего шума и пыли", и никто мне не парит мозг из-за того, что пользователям вздумалось числовые данные отформатировать как текст, или из-за того, что Excel в очередной раз не к месту отличился умом и сообразительностью, преобразовав текст в число. Последний раз редактировалось gl00mie; 25.01.2013 в 12:48. |
|
25.01.2013, 13:50 | #12 |
Участник
|
Цитата:
Сообщение от Gustav
Попробуйте принудительно "дернуть" значение ячейки после наложения на нее формата "Текстовый" (выражаюсь на VBA):
Range("A1").Value2 = "'" & Range("A1").Value2 (это известная операция добавление ведущего апострофа) или так Range("A1").Value2 = Range("A1").Value2 & "" (здесь просто пустая строка добавляется) "Чтобы продать что-нибудь ненужное, нужно сначала купить что-нибудь ненужное, а у нас денег нет" Цитата:
На самом деле непонятно откуда Excel берёт информацию о типе ячейки, потому что отображает он её корректно в текстовом виде, а хранит получается что как число |
|
25.01.2013, 14:18 | #13 |
Moderator
|
Цитата:
|
|
25.01.2013, 16:40 | #14 |
Участник
|
Цитата:
Нестроковые значения хранятся непосредственно в ячейках и их тип определяется самими данными. Когда меняется формат ячейки, значение в ней хранящееся не переносится в эту область, а остается в ячейке (по сути, меняется лишь отображение этих данных, что хорошо видно на примере дат). Если тип ячейки текстовый или указан перед данными апостроф, то вносимое значение всегда будет сохраняться в разделяемой области. PS Для получения текстового значения ячейки независимо от типа хранимых в ней данных можно пользоваться функцией Text() вместо Value() или Value2()
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Logger (10). |
25.01.2013, 17:41 | #15 |
Moderator
|
про .Text()
|
|
|
За это сообщение автора поблагодарили: mikki_messer (1). |
25.01.2013, 20:28 | #16 |
Участник
|
__________________
Axapta v.3.0 sp5 kr2 |
|
Теги |
excel, импорт, импорт из excel |
|
|