本人為小白,此篇僅為記錄自己初次接觸C# VSTO寫Excel插件遇到的一些問題。
一、遇到的問題
1.如何獲取當前的Excel文件;
2.如何當前表格有多少行(不算解決);
3.如何獲取鼠標選中的區域;
4.調試的時候如何才能打印出一些變量的值(未解決);
5.調試的時候Excel表對應的位置沒有顯示插件的界面;
6.插件發布之后的安裝和卸載;
二、解決方法
1.獲取當前的Excel文件
在寫代碼之前有兩個集合是必須被引用的:
1 using Microsoft.Office.Tools.Ribbon; 2 using Excel = Microsoft.Office.Interop.Excel;
首先使用全局變量類Globals獲取一個Excel應用的進程(具體關於Globals我也不是很了解,只知道它可以用在這里),其中的Globals.ThisAddIn指的就是當前正在編寫的插件。
1 public Excel.Application app; 2 app = Globals.ThisAddIn.Application;
其次通過Excel.Application類型的變量app就可以獲取當前的工作簿(就是現在打開的Excel文件)、當前的表格、當前的單元格
public Excel.Workbook wb; wb = app.ActiveWorkbook;//當前的工作簿 public Excel.Worksheet worksheet; worksheet = app.ActiveSheet;//當前的表格 public Excel.Range cell; cell = app.ActiveCell;//當前的單元格
而所謂的當前的表格指的就是Excel界面左下方被選中的sheet(如Sheet1),當前的單元格就是指被鼠標單擊一次之后被綠框包圍的單元格(如D2)。

打開Excel文件也就是工作簿,還可以使用文件路徑打開(獲得對象和上方ActiveWorkbook相同)。Open方法中第一個參數是文件路徑,剩下是14個Type.Missing(這些參數具體只能查看官方文檔)。
string fileName = app.ActiveWorkbook.FullName;//獲得當前excle的絕對路徑 Excel.Workbook w = app.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
2.如何獲得當前表格有多少行;
我采用的是遍歷的方法,遍歷第一列的所有行。每一行都判斷這一行是否為null,如果不是就把行數加1,如果是null則調用IsOver函數判斷該行下方是否有連續1000個空行,如果沒有連續1000個空行就認為該表格還沒有到最后一行的下一行,行數繼續加1,而如果有連續的1000個空行則認為該表格已經到達了最后一行的下一行,到此整個表格的所有行都遍歷了一遍,跳出死循環,活動行數rowCount;
這樣的方法很明顯不是最好的方法,它很局限,如果存在一個兩行數據之間有1000多個空行的表格(這種情況應該很少吧),或者存在第一列沒有任何數據或字符的表格,或者存在第一列最后一行的行數並不是最大行數的表格,那么我這個方法將會不在有效。因此我認為自己並沒有解決這個問題。
如果有大佬知道正確的獲取表格行數的方法,希望可以告訴我。
1 public int rowCount = 0;//數據的行數 2 public int count;//row的更改次數 3 4 if (count == 0)//rowCount只改變一次 5 { 6 while (true)//獲取表格總行數 7 { 8 if (worksheet.Cells[i, 1].value == null && IsOver(i)) 9 break; 10 rowCount++; 11 i++; 12 } 13 count++; 14 } 15 16 17 public bool IsOver(int i)//是否連續有x個空格,是返回True 18 { 19 int c = 0;//代表連續的空格數量 20 int x = 1000;//最多有多少個連續的空格結束 21 while (c<x) 22 { 23 if (worksheet.Cells[i, 1].value != null) 24 return false; 25 c++; 26 i++; 27 } 28 return true; 29 }
3.如何獲取鼠標選中的區域
先把我找到的解決辦法的網址放在這里。https://stackoverflow.com/questions/2110327/excel-getting-the-selected-rows-back
由於我現在只需要獲得一塊鼠標選中的區域,不需要獲得多個區域,所以下方的代碼只能獲得一塊鼠標選中的區域(如果需要多個區域的話,希望上面這個網址的內容能對你有啟發)。
Excel.Application 這個類中的Selection屬性返回的是一個Excel.Range類型的值,就是鼠標選中的區域,暫且將他命名為range。無論你怎么框選單元格,range.row和rang.column永遠都是框選區域左上角的的行數和列數,這遠不能獲得鼠標選中的整個區域,我們還需要左下角和右上角的行數和列數。range.Rows和range.Columns返回的是都是Excel.Range類型的值,它們所代表的的是鼠標框選區域的所有行和所有列,之后只需要使用foreach將它們遍歷,記錄遍歷的最后一行的行號和最后一列的列號,就得到了左下角的行號和右上角的列號。到此獲得了左上角,左下角和右上角三個單元格的行號和列號,也就是獲得了整個鼠標所框選的區域。
1 private int firstR;//左上角的行數 2 private int firstC;//左上角的列數 3 private int rightC;//最右邊的列數 4 private int downR;//最下邊的行數 5 6 public void GetSelectArea()//獲取鼠標選中的區域 7 { 8 Excel.Range range = app.Selection;//獲取鼠標選中的區域 9 //List<int> rowNumber = new List<int>();//某區域所有的行數 10 //List<int> columnNumber = new List<int>();//某區域所有的列數 11 12 13 firstC = range.Column;//獲取左上角的列數 14 firstR = range.Row;//獲取左上角的行數 15 foreach (Excel.Range row in range.Rows) 16 { 17 downR = row.Row;//全部行遍歷一遍之后就可以得到最后一行的行號 18 } 19 foreach (Excel.Range column in range.Columns) 20 { 21 rightC = column.Column;//同樣,全部列遍歷一遍之后就可以得到最好一列的列號 22 } 23 }
4.調試的時候如何才能打印出一些變量的值(未解決);
調試程序時如果我要查看某一個變量的值,我現在只會將變量的值打印在Excel的某個單元格中查看。
1 worksheet.Cells[1, 5].value = $"{rowCount}";
但我如何才能像平時一樣在那個黑框框里打印出來,或者在Visual Studio里查看。如果有大佬知道方法,求指教。
5.調試的時候Excel表對應的位置沒有顯示插件的界面;
我遇到這個問題是因為我不小心把我這個項目從Excel開發工具-->COM加載項的列表中刪除了(開發工具這個選項卡默認是沒有開啟的,需要自己開啟)。
只要點擊Visual Studio里生成-->清理解決方案(或者清理+你的項目名)之后,再次調試就可以了。

6.插件發布之后的安裝和卸載;
假如寫好插件之后想要把插件給別人用,只需要把這里改成Rlease,然后點擊生成-->發布。

點擊發布后修改發布的位置(點擊下一步之后的其他修改我也不知道有什么作用)。點擊完成即可。

將發布位置對應的這三個文件打包發給別人,讓他運行里邊的setup.exe就可以使用你寫好的插件。

最后關於如何卸載自己的這個插件,我真是找了老半天。需要在Windows的應用管理里搜索你的項目名,也就是上3個文件中第二個文件的名字就可以卸載了。

