[MOSS]利用SSIS抓取存放在MOSS上文件庫的Excel轉入資料庫中
之前轉入Excel的資料都是開放Server上的資料夾作分享
再利用SSIS的Excel資料來源作轉入的動作
而現在有一個需求是要轉入海外同仁維護的Excel資料
但是目前公司的File Share跟海外是不相通的
原本有考慮要利用同步檔案的做法
將海外的檔案在固定時間將檔案同步回來
但是因為怕海外的檔案若有緊急更改
又有馬上要更新資料的需求
這樣顯得不夠彈性
所以後來就決定讓海外的同仁將檔案上傳到MOSS上
再由SSIS抓取檔案轉入資料
那麼第一個要解決的就是該如何抓到MOSS上的Excel檔案
我這邊的做法是利用MOSS提供的Web Service來抓資料
所以在IS上先拉一個資料流程元件
來源用「指令碼元件」
指定完輸出的資料行之後,就可以開始著手寫程式了
首先加入Excel的Web Service參考
路徑是:http://[Server]/_vti_bin/ExcelService.asmx
C#
1: /* Microsoft SQL Server Integration Services Script Component
2: * Write scripts using Microsoft Visual C# 2008.
3: * ScriptMain is the entry point class of the script.*/
4:
5: using System;
6: using System.Data;
7: using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
8: using Microsoft.SqlServer.Dts.Runtime.Wrapper;
9: using SC_5b598c57224f45b2b97f422c8fa7d64c.csproj.ChilinkExcelService;
10:
11:
12: [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
13: public class ScriptMain : UserComponent
14: {
15: private SC_5b598c57224f45b2b97f422c8fa7d64c.csproj.ChilinkExcelService.ExcelService Es = null;
16: public DataTable dt;
17: RangeCoordinates rangeCoordinates = new RangeCoordinates();
18: string sheetName = "Sheet1";
19:
20: public override void PreExecute()
21: {
22: base.PreExecute();
23: /*
24: Add your code here for preprocessing or remove if not needed
25: */
26: Es = new ExcelService();
27: //Excel excel = new ChilinkExcelService.ExcelService();
28: Es.Credentials = new System.Net.NetworkCredential("帳號", "密碼", "網域");
29:
30: Status[] stati;
31: String sessionID = Es.OpenWorkbook("檔案路徑", "en-US", "en-US", out stati);
32:
33: rangeCoordinates.Column = 0; //從0開始算,從第一欄開始抓
34: rangeCoordinates.Row = 1; //從0開始算,指從第二列開始算(第一列是標題)
35: rangeCoordinates.Height = 2;
36: rangeCoordinates.Width = 8;
37:
38: dt = new DataTable();
39: dt.Columns.Add("Sorting_Date", System.Type.GetType("System.DateTime"));
40: dt.Columns.Add("Model_name");
41: dt.Columns.Add("Item_No");
42: dt.Columns.Add("People_No");
43: dt.Columns.Add("Hours");
44: dt.Columns.Add("Human_Cost");
45: dt.Columns.Add("Meal_Cost");
46: dt.Columns.Add("Traffic_Fee");
47:
48: object[] rangeResult = Es.GetRange(sessionID, sheetName, rangeCoordinates, true, out stati);
49:
50: for (int i = 0; i < rangeResult.Length; i++)
51: {
52: DataRow row = dt.NewRow();
53: row["Sorting_Date"] = Convert.ToDateTime(((object[])rangeResult[i])[0]);
54: row["Model_name"] = ((object[])rangeResult[i])[1];
55: row["Item_No"] = ((object[])rangeResult[i])[2];
56: row["People_No"] = ((object[])rangeResult[i])[3];
57: row["Hours"] = ((object[])rangeResult[i])[4];
58: row["Human_Cost"] = ((object[])rangeResult[i])[5];
59: row["Meal_Cost"] = ((object[])rangeResult[i])[6];
60: row["Traffic_Fee"] = ((object[])rangeResult[i])[7];
61: dt.Rows.Add(row);
62: }
63:
64:
65:
66: }
67:
68: public override void PostExecute()
69: {
70: base.PostExecute();
71: /*
72: Add your code here for postprocessing or remove if not needed
73: You can set read/write variables here, for example:
74: Variables.MyIntVar = 100
75: */
76: }
77:
78: public override void CreateNewOutputRows()
79: {
80: /*
81: Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
82: For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
83: */
84: foreach (DataRow row in dt.Rows)
85: {
86: OutBuffer.AddRow();
87: OutBuffer.SortingDate =Convert.ToDateTime( row["Sorting_Date"]);
88: OutBuffer.Modelname = row["Model_name"].ToString();
89: OutBuffer.ItemNo = row["Item_No"].ToString();
90: OutBuffer.PeopleNo =Convert.ToInt32( row["People_No"]);
91: OutBuffer.Hours = Convert.ToInt32(row["Hours"]);
92: OutBuffer.HumanCost = Convert.ToInt32(row["Human_Cost"]);
93: OutBuffer.MealCost = Convert.ToInt32(row["Meal_Cost"]);
94: OutBuffer.TrafficFee = Convert.ToInt32(row["Traffic_Fee"]);
95: }
96:
97: OutBuffer.EndOfRowset();
98:
99: }
100:
101: }
先利用Web Service提供的OpenWorkbook Method
取得SessionID
但是在開啟的時後就發生[you do not have permissions to open this file]錯誤
這個原因是因為沒有將檔案的路徑加入MOSS信任的檔案位置
加入的方法是到
[MOSS管理中心] –> [應用程式管理] –> [Office SharePoint Server 共用服務] –>
[建立或設定此伺服器陣列的共用服務 ] –> [SharedServices1(預設) ] –> [Excel Services 設定]
在[信任的檔案位置]中加入要抓資料的路徑
這樣就能解決沒有權限的問題
再來就是抓資料了,
我這裡是使用Web Service提供的GetRange Method
這裡有遇到2個問題
第1個是當轉入日期格式時,
並不會轉入正確的格式,
後來發現是要將formatted 參數設為 true
第2個就是要使用RangeCoordinates
但是因為資料是user一直維護的
而RangeCoordinates是需要設定資料的範圍
所以無法確定資料的筆數
目前還找不到什麼比較好的方法可以得到資料筆數
原本要用 Sheet.UsedRange.Rows.Count
但是因為在開啟Excel時,還需要輸入登入帳密
最差的做法我想應該就是直接去找每一格直到找到空白為止(上限為Excel能放的筆數)
抓完資料就直接丟到datatable中
輸出資料時再丟出來
參考資料:
OpenWorkbook Method
GetRange Method
you do not have permissions to open this file
http://technet.microsoft.com/en-us/library/cc261678(office.12).aspx
Excel資料筆數
http://www.blueshop.com.tw/board/show.asp?subcde=BRD20061227150227J09&fumcde=FUM200501271723350KG