Suvendu Shekhar Giri Ответов: 1

Имя листа не заканчивается символом доллара ( $ )


ОБНОВЛЕНИЕ:
Я откладываю свой вопрос.
Я получил некоторую подсказку и пропустил несколько вещей, о которых нужно упомянуть здесь.
Извините, что трачу ваше драгоценное время. Очень скоро я обновлю этот вопрос и тоже опубликую ответ, если мне это удастся.

Спасибо всем за ваше драгоценное время.


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

Проблема: В одном из моих проектов я написал некоторый код для чтения строк данных из листа excel примерно следующим образом-
System.Data.OleDb.OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [" + SheetName + "]", con);

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

Я пошел на отладку и обнаружил, что для этого конкретного файла имя листа является просто именем (т. е. "Лист1") и не заканчивается символом доллара("$") в конце. Но для других файлов он поставляется с требуемым $ символ.

Когда я изменил код, чтобы добавить символ$, если его еще нет, код работал нормально. Все файлы находятся в одном и том же формате, т. е., .xlsx

Может ли кто-нибудь просветить меня на этот счет, если я упускаю здесь что-то основное?
Любая ссылка на хорошую статью/документацию также была бы полезна.

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

Заранее спасибо!

Что я уже пробовал:

-- Отладка, чтобы выяснить проблему, как упоминалось выше

CHill60

Где эта переменная SheetName назначили?
У меня есть опытные пользователи, переименовывающие файл в filename.xls и ожидая, что он волшебным образом превратится в электронную таблицу Excel (!). Возможно, это просто "сломанный" файл.

Suvendu Shekhar Giri

Я получаю имена листов, используя GetOleDbSchemaTable()
Однако файл открывается правильно с помощью MS Excel.

Richard MacCutchan

Как вы получаете имя листа из файла?

Suvendu Shekhar Giri

Всем привет!
Я откладываю свой вопрос.
Я получил некоторую подсказку и пропустил несколько вещей, о которых нужно упомянуть здесь.
Извините, что трачу ваше драгоценное время. Очень скоро я обновлю этот вопрос и тоже опубликую ответ, если мне это удастся.

Спасибо всем за ваше драгоценное время.

1 Ответов

Рейтинг:
1

Jochen Arndt

Я не могу дать окончательного ответа, но тоже наткнулся на это несколько лет назад. Вот что я могу извлечь из своих комментариев к исходному коду C++.

OLE DB (и ODBC) - это интерфейсы баз данных, которые обрабатывают файлы Excel как базы данных. Они используют два типа таблиц, которые представляют здесь интерес: системные таблицы и обычные таблицы. С помощью драйверов Excel системные таблицы сопоставляются с листами Excel (со знаком доллара), а обычные таблицы-с именованными диапазонами (без знака доллара).

При создании листов с помощью Excel будет только один лист (системная таблица). Но при использовании драйвера ODBC для создания листа создаются оба типа (это также может относиться к OLE DB, но я не уверен).

Вы не указали, как вы получаете имена листов. Но я думаю, что вы используете что-то похожее на мой метод
[РЕДАКТИРОВАТЬ: GetOleDbSchemaTable() упомянуто между тем в комментарии] Вы используете что-то похожее на мой метод получения имен таблиц: [/EDIT]
Я перечисляю таблицы, используя ADODB::adSchemaTables и получать имена от TABLE_NAME поле. Но это вернет все таблицы (системные таблицы и обычные таблицы), так что могут быть дубликаты записей. Существует также TABLE_TYPE поле. Но это поле всегда возвращается TABLE (Обычная таблица) и никогда SYSTEM_TABLE; даже для системных таблиц (листов). Похоже, это жучок. Ссылка: OleDbSchemaGuid.Поля Таблицы (Системы.Данных.Для oledb)[^].

Таким образом, вы можете получить имя без знака доллара, когда лист был создан с помощью ODBC (или, возможно, также с помощью OLE DB). Вы можете спросить своего клиента, относится ли это к неудачному файлу, чтобы доказать это.

Однако имя может также ссылаться на именованный диапазон, а не на лист.

Решение, которое я использовал:
Я перечисляю таблицы и сохраняю результаты в списке. Если переданное имя не имеет завершающего знака доллара, оно добавляется. Если этого имени нет в списке, оно добавляется. Поэтому я избегаю повторяющихся записей и тоже отношусь к обычным именам таблиц как к листам. Но это будет игнорировать существование именованных диапазонов, которые имеют имена, которые не используются для листов.


Suvendu Shekhar Giri

Спасибо за ответ и предложения. Проверю и скоро свяжусь с вами.

Jochen Arndt

Тем временем вы упомянули, что используете GetOleDbSchemaTable(); вероятно, используя код, подобный примеру кода на странице MSDN.

Мое предположение:
Это запрашивает таблицу типов. Если существует только системная таблица (лист), она вернет имя для нее. Но если существует также Обычная таблица (именованный диапазон) с тем же именем, она вернет имя этой таблицы без '$'.