# 獲取 sheet 名字
可看“項目管理臺賬.sln”的“登錄窗口”,或者看“連接測試”,代碼在里面的“sheet 表名”窗口。
SqlClient.SqlConnection沒有相關的功能,所以要用 OleDbConnection。
[https://www.cnblogs.com/coolsundy/p/4056813.html](https://www.cnblogs.com/coolsundy/p/4056813.html)
[https://www.cnblogs.com/CharlesGrant/p/3650864.html](https://www.cnblogs.com/CharlesGrant/p/3650864.html)
可以理解為:兩個都是 c#中用于獲取外部數據的類,但 sql 是獲取 sqlserver 數據庫使用,而 OleDb 可以認為是獲取與 Microsoft 有關的比如 excel、access 數據庫時候用的。
與 sql 一樣,ole 也要寫查詢語句。sql 查詢語句比如是“select \* from dbo.總工辦數據庫”,那么 ole 語句可能是“select \* from [sheet1$]”。這里跟的是表名。
## 做法 1
如果要求大家在導入數據的時候直接把 excel 表格另存,然后 sheet 名就直接叫 sheet1 的話,那上面的語句沒問題。
但有時候大家的表往往不一定是sheet1名字,所以可以用 oleConnection 來判斷,獲取 sheet 的名字。
## 做法 2
用以下“做法 2 具體”中提到的辦法獲取 sheet 各個表的名字。sheet的名字其實是按“正序”排列的,然后默認讀取第一行的表。
1. 當sheet命名成“你好” 以及“玉米” 的時候,第一行顯示的表名 是“你好”;

2. 當sheet命名成“1玉米” 以及“2你好”的時候,順序就不一樣了。

## 做法 3
獲取當前 active 的表格(未完成)
## 做法 2具體:在不考慮 sheet 被重命名的情況下

> 基本邏輯:
> 1. 把 excel 當成一個數據庫,那么每個 sheet 就是一個表;
> 2. 用 OleDbConnection.GetOleSchema()方法來獲取每個 sheet 的屬性;括號中,第一個元素要用 OleDbSchemaGuide來實現;
> - 此時創建的是OleDbConnection對象 oleconn;
> 3. 獲取的屬性實際上是一個數組,則用 DataTable (比如命名為 dt)來存放;
> 關鍵的代碼只有這一句: `DataTable dt = oleconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null) `
> 4. 遍歷 dt,一般獲取第一行第一列的值,這個值就是我們要找的 sheet 名了;(此部分本次未寫,知道了 dt 結構以后,就可以方便寫出來。)datagridview控件用的 是datagridview1.Rows[0].Cells[2]或者Cells["密碼"]
> 
> [http://www.hmoore.net/amy326/c/798326](http://www.hmoore.net/amy326/c/798326)
> 5. 返回這個值。
完整代碼如下:
```
public class pb\_公共類
{
//主要目的是為了獲得表名,但由于ole的連接字符比較復雜,所以單獨出來寫
//1獲取ole連接字符connString
public String GetExcelConn()
{
string connString = "";
OpenFileDialog ofd = new OpenFileDialog();
ofd.ShowDialog();
ofd.Filter = "Excel(\*.xls)|\*.xls|Excel(\*.xlsx)|\*.xlsx";
var path = ofd.FileName;
string filesuffix = Path.GetExtension(path);
if(string.IsNullOrEmpty(filesuffix))
{
return null ;
}
else if(filesuffix == ".xls")
{
return connString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + ";Extended Properties=\\"Excel 8.0;HDR=YES;IMEX=1\\"";
}
else
{
return connString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + path + ";" + ";Extended Properties=\\"Excel 12.0;HDR=YES;IMEX=1\\"";
}
}
public DataTable GetTableName()
{
string connString = GetExcelConn(); // 直接用上面第一步獲得的返回值來用,變量名也可以是其他的abc之類的,無所謂
OleDbConnection oleconn = new OleDbConnection(connString);
oleconn.Open();
DataTable dt = oleconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);//只要這一句就可以了!
oleconn.Close();
return dt;
}
```


最后在用一個dataGridView控件顯示即可。

# 但 excel 里面 sheet 的名字,跟它的編號其實不是同一個
就像 textbox 有“name”和“text”兩個屬性一樣。一個是這個東西本身系統生成時候的名字,一個是我們讓它顯示在前端時候我們給它命名的名字
比如:打開 excel VBA。用戶已經給 sheet隨意命名了。但在 vba 里面可以看到,即使用戶命名的叫“sheet2”,但 excel 中系統標注的這個表的代號仍然實際是 sheet1。
> **所以在c#中使用的時候要注意,不要因此引起運行結果的錯亂。**

# 表名顯示錯誤
https://blog.csdn.net/hbxtlhx/article/details/8511731
如下圖:明明excel里面只有一個表,但是用工具弄出來以后變成有好幾個表。還有一個隱藏的“'2019年貴州項目A4費用表'$_FilterDatabase”。


## 打開Excel - 公式 - 名稱管理器
并未看到任何記錄。所以有可能這個表格被隱藏了。

VBA中新建模塊輸入以下代碼,并運行
```
Sub ShowAllNames()
For Each n In ThisWorkbook.Names
n.Visible = True
Next
End Sub
```
再打開公式-名稱管理器,則可以看到隱藏的這個表格。 如果沒必要,可以刪除。

刪除完再運行,就都正常了。

- 幫助文檔 microsoft helo viewer
- c#開發環境及visual studio安裝注意事項
- c#程序基本結構-基本語法
- Q1: public static void main(String[] args) 是什么意思
- Q2: c#命名空間+Main方法
- Q3:注釋+命名規則+代碼規則
- Q4: c#語句 system => console
- Q5: 數據類型 .net
- Q5: 常用名字、變量、運算符
- Q6: 對話窗輸入-屬性
- Q7: 遞歸
- Q8:決策分支、條件判斷語句 if 語句
- Q9:數組
- Q10:字符串
- Q11:對象、類、訪問權限、靜態動態函數
- Q12:方法及參數——繼承于類
- Q13:構造函數
- Q14:繼承——base 關鍵字
- Q15:多態、虛方法、接口
- Q16:創建窗體應用、控件
- Q17:Ado數據訪問、連接 sqlserver 數據庫
- Q18: 讀取數據command + DataRead( )、DataSet + DateAdapter
- Q19: Entity Framwork、entity 與 ADO.net的區別
- Q20: 對話框、文件、文件夾
- Q21: 導入excel數據、更新到 dbo 數據庫中
- Q26: 獲取 excel 中每個 sheet 的表名
- Q22: 兩個窗體之間數據+方法傳遞
- Q23: 數學對象
- Q24: c#網站編寫
- Q25: visual studio2017如何查看幫助
- Q27: c# dictionary 字典對象
- Q28: 數組與dataTable互相轉化