上一篇文章「在WSH環境下存取Access資料庫」中,使用組合SQL語法的方式將資料寫進資料庫,但這樣的方式在資料欄位數量較多時,是種相當痛苦的處理方法。
這篇嘗試使用ADODB.RecordSet物件來跟資料庫打交道,雖然以前只用過Delphi程式語言設計資料庫軟體,好在ADODB物件的用法差異並不會太大,語法、結構也都很類似(就是開資料庫連線、建立資料集、最後記得關閉資料庫連線‧‧‧等等),參考網路上的一些資料後,就試著動手寫寫看。
改以ADODB物件寫入Access的完整程式碼如下:
<?xml version="1.0" standalone="yes" encoding="big5"?>
<package>
<job>
<script src="JScript/adojavas.js" type="text/javascript" language="javascript" charset="utf-8"></script>
<script type="text/javascript" language="javascript" charset="utf-8">
<![CDATA[
/**
*
* 取得資料。
*
* @author ace
*
* @version 2010/11/11 v0.1
*
* @param {String} astrStockCode 股票代碼。
*
* @returns {String} 網頁資料。
*
* @requires Microsoft.XMLHttp
*
*/
function getHttp(astrStockCode) {
var strReturn = new String("");
var strURL = new String("http://tw.stock.yahoo.com/q/q?s=" + astrStockCode);
var objXMLHttp = new ActiveXObject("Microsoft.XMLHttp");
objXMLHttp.open("GET", strURL, false, "");
objXMLHttp.send();
// todo: 加入是否正確取得資料之判斷式。
var strReturn = new String(objXMLHttp.responseText);
return strReturn;
}
/**
*
* 剖析html資料。
*
* @author ace
*
* @version 2010/11/11 v0.1
*
* @param {String} astrTrnDate 交易日期。
* @param {String} astrStockCode 股票代碼。
*
* @returns {Array} 陣列資料。
*
*/
function parseHTML(astrTrnDate, astrStockCode, astrContent) {
var objReturn = new Array();
/**
*
* 建立瀏覽器物件。
*
* @author ace
*
* @version 2010/11/16 v0.1
*
* @see <a href="http://us.generation-nt.com/answer/parsing-html-jscript-help-59686112.html">Parsing HTML with JScript</a>
* @see <a href="http://www.eggheadcafe.com/software/aspnet/36239301/jquery.aspx">Jquery</a>
*
*/
var htmlfile = new ActiveXObject("htmlfile");
var window = htmlfile.parentWindow;
var navigator = window.navigator;
var document = window.document;
var location = document.location;
window.ActiveXObject = {};
// todo:載入html檔案發生錯誤時,無法被JavaScript的catch語法攔截?!
htmlfile.open();
htmlfile.write("<script type=\"text/javascript\">window.onerror = function () {};</script>");
htmlfile.write(astrContent);
htmlfile.close();
var objTR = document.getElementsByTagName("tr");
for (var intIndex = 0; intIndex < objTR.length; intIndex++) {
var objTD = objTR[intIndex].getElementsByTagName("td");
if (objTD.length == 12) {
objReturn.push(astrTrnDate);
objReturn.push(astrStockCode);
objReturn.push(objTD[2].firstChild.innerHTML); // 成交金額多了<b>標籤,再往下一個結點取資料。
objReturn.push(objTD[3].innerHTML);
objReturn.push(objTD[4].innerHTML);
objReturn.push(objTD[6].innerHTML.replace(",", ""));
objReturn.push(objTD[7].innerHTML);
objReturn.push(objTD[8].innerHTML);
objReturn.push(objTD[9].innerHTML);
objReturn.push(objTD[10].innerHTML);
break;
}
}
return objReturn;
}
/**
*
* 寫入Access資料表。
*
* @author ace
*
* @version 2010/11/30 v0.1
*
* @param {String} astrTrnDate 交易日期。
* @param {String} astrStockCode 股票代碼。
* @param {Array} aobjData 資料陣列。
*
* @return
*
* @description 2010/11/30 陣列資料內容:
* aobjData[0]:交易日期。
* aobjData[1]:股票代碼。
* aobjData[7]:開盤價格。
* aobjData[8]:最高價格。
* aobjData[9]:最低價格。
* aobjData[2]:收盤價格。
* aobjData[5]:成交張數。
* @description 2010/12/26 改以RecordSet物件寫入資料。
*
*/
function insertAccess(astrTrnDate, astrStockCode, aobjData) {
var objConn = WScript.CreateObject("ADODB.Connection");
var objRS = WScript.CreateObject("ADODB.RecordSet");
try {
strDatabase = new String("Stock.mdb");
objConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDatabase;
objConn.Open();
var strSQL = "select * from stocks_day_trn_log where 1=1 and trn_date='" + aobjData[0] + "' and stock_code='" + aobjData[1] + "' ";
objRS.Open(strSQL, objConn, adOpenStatic, adLockOptimistic, adCmdText);
// 若查無資料則新增。
if (objRS.EOF == true) objRS.AddNew();
objRS("trn_date") = aobjData[0];
objRS("stock_code") = aobjData[1];
objRS("open_price") = aobjData[7];
objRS("high_price") = aobjData[8];
objRS("low_price") = aobjData[9];
objRS("close_price") = aobjData[2];
objRS("trn_qty") = aobjData[5];
objRS.Update();
}
catch (e) {
throw e;
}
finally {
objRS.Close();
objConn.Close();
}
}
// Program Start Here
try {
var objToday = new Date();
// 以系統日期當作交易日期,理想作法應以網頁記載時間為準。
var strTrnDate = new String("");
strTrnDate = objToday.getFullYear().toString() + (objToday.getMonth() + 1).toString() + objToday.getDate().toString();
var strStockCode = new String("2002");
insertAccess(strTrnDate, strStockCode, parseHTML(strTrnDate, strStockCode, getHttp(strStockCode)));
}
catch (e) {
WScript.Echo("執行過程有誤,錯誤訊息:" + e.description);
}
]]>
</script>
</job>
</package>
與前一篇文章「在WSH環境下存取Access資料庫」的作法對照,寫法更加簡潔,至少不用自己計算單引號的位置與個數(這是很容易出錯的地方)。看來想在WSH環境下跟資料庫打交道,把ADODB物件的用法摸熟會是一個比較好的資料處理方式。
補充記錄:在上面的程式碼第5行中所載入的adojavas.js檔案是藉由修改ASP環境所提供的adojavas.inc檔案而來;如果電腦上有安裝ADO元件,可以在C:\Program Files\Common Files\System\ado資料夾下找到adojavas.inc檔案,把副檔名修改成js,並將檔案內容前後的「<%」與「%>」符號移除,就可以直接引用該檔案已經定義好的常數值(例如程式碼第145行的adOpenStatic),省去自行訂義的麻煩。
沒有留言:
張貼留言