[MOSS]利用SSIS抓取存放在MOSS上文件庫的Excel轉入資料庫中

  • 2934
  • 0

[MOSS]利用SSIS抓取存放在MOSS上文件庫的Excel轉入資料庫中

之前轉入Excel的資料都是開放Server上的資料夾作分享

再利用SSIS的Excel資料來源作轉入的動作

而現在有一個需求是要轉入海外同仁維護的Excel資料

但是目前公司的File Share跟海外是不相通的

原本有考慮要利用同步檔案的做法

將海外的檔案在固定時間將檔案同步回來

但是因為怕海外的檔案若有緊急更改

又有馬上要更新資料的需求

這樣顯得不夠彈性

所以後來就決定讓海外的同仁將檔案上傳到MOSS上

再由SSIS抓取檔案轉入資料

那麼第一個要解決的就是該如何抓到MOSS上的Excel檔案

我這邊的做法是利用MOSS提供的Web Service來抓資料

所以在IS上先拉一個資料流程元件

 

來源用「指令碼元件」

image

 

指定完輸出的資料行之後,就可以開始著手寫程式了

image

 

首先加入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

http://msdn.microsoft.com/en-us/library/microsoft.office.excel.server.webservices.excelservice.openworkbook.aspx

GetRange Method

http://msdn.microsoft.com/en-us/library/microsoft.office.excel.server.webservices.excelservice.getrange.aspx

you do not have permissions to open this file

http://developers.de/blogs/nadine_storandt/archive/2007/09/06/moss-excel-services-you-do-not-have-permissions-to-view-this-workbook.aspx

http://technet.microsoft.com/en-us/library/cc261678(office.12).aspx

Excel資料筆數

http://www.blueshop.com.tw/board/show.asp?subcde=BRD20061227150227J09&fumcde=FUM200501271723350KG