前言
今年五月發布的 ”EXCEL各欄位內容之合計算出”,當時使用的方法是須要開啟EXCEL檔案,利用函數讀取全部資料以便計算,若有6個項目需要計算,就需讀取 6次全部的資料,雖然可以完成6個計算項目處理,但處理效率較差。
今回新設計vbs程式,在不須開啟EXCEL 程式之下,可以讀取資料一次,就能完成數個項目的計算處理。1.處理目的
設計Vbs程式,依據excel資料內容,自動計算出各項目數值,以增加處理速度,避免人為錯誤,提升工作效率,迅速掌握單位內業務推進狀況。
2.處理說明:
程式自動讀取excel檔案,自動計算,並將更新後excel儲存。
2.1 設計bat執行檔,指定欲處理的excel檔案路徑,以便vbs程式執行時,可以讀取excel資料
2.2 vbs程式執行時,一筆一筆讀取excel資料,處理各項計算公式,以便取得所需數值
2.3 資料逐筆讀取,以迴圈處理相同計算公式後,最後將更新的excel檔案,作實體檔案儲存動作
3.Bat 設計說明:
新設計bat執行檔,利用bat所設定之參數,指定excel檔案所在位置,以便vbs程式可以順利讀取excel檔案
4. 實例說明:
以某單位每月志工服務時數明細之excel資料檔為例,程式執行後,取得計算後合計數值,將其寫入excel檔內,並儲存excel檔案
4.1 讀取志工服務時數之檔案資料,其內容如下參考

志工服務時數明細之excel資料檔
4.2 vbs執行時,
*男女判斷條件,以身分證號之第二字元為依據,
1: 表男生; 2: 表女生
*6個 計算項目,如下
男志工服務人數
女志工服務人數
合計服務人數
男志工服務時數
女志工服務時數
合計服務時數
4.3 服務分鐘合計之特別處理
*服務分鐘須換算為時數,即服務 30分鐘,改為 0.5小時
*設計副程式Sub M2H_c(MF_f),以處理依據男女別,各別累計男女志工的服務時數
4.4 excel資料全部處理完後,將計算後的數值,依據本次讀取資料的月份,存放於excel內該當月份欄位。即讀取資料為 6月份,就自動存放在excel表單的 6月份欄位內,
若下月執行時,資料為 7月份,程式會自動存放在excel表單的 7月份欄位內
vbs程式實際執行後,產出結果,如下參考

本月程式執行後,寫入報表6月份欄位內,並於右上方記入更新月為11406
5.bat設計如下 :
5.1 名稱: VHCal2.bat
5.2 內容:
WScript VHCal2.vbs "D:\lin_PC\EXCEL\志工時數\服務人數時數計算.xlsx"
5.3 bat執行方法
* 直接於bat存放路徑,按兩下執行bat
* 亦可於桌面新設bat捷徑圖示,於圖示按兩下執行bat,如下圖

- bat執行後,正常結束時,出現訊息如下

6.vbs設計如下:
6.1 名稱: VHCal2.vbs
6.2 程式碼內容如下:
'REM--- 本xxx.vbs 儲存時,編碼方式,須為ANSI,否則msgbox 中文訊息會顯示亂碼
'REM--- read excel sheet1 to do some cals, last to update(rewrite) excel sheet2
'Rem--- from bat arguments to get the path of this excel ---
if WScript.Arguments.Count < 1 Then
WScript.Echo"找無excel檔案! (Please specify the xlsx file path !)"
Wscript.Quit
End If
'REM--- get path of excel file from argumnt ---D:\lin_PC\EXCEL\志工時數\服務人數時數計算.xlsx
Set objFSO = CreateObject("Scripting.FileSystemObject")
excelP = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
set arg = WScript.arguments
Dim excelAPP ' as excel object
Dim wkBook ' as workbook
DIM sheetB,sheetR
'REM--- 首先建立 Excel 物件,使用ComObj:
Set excelAPP = CreateObject("Excel.Application")
excelAPP.Visible = false
Set wkBook = excelAPP.Workbooks.Open(excelP) 'REM--- 開啟已存在的工作簿excel file
Set sheetR = wkBook.workSheets(2)
Set sheetB = wkBook.workSheets(1)
'SET sheetB = wkBook.workSheets("志工基本資料")
MP_c = 0
MH_c = 0
FP_c = 0
FH_c = 0
sheetB.Activate 'REM-----設定為活動工作表
Crow = sheetB.UsedRange.Rows.Count
'Ccol = sheetB.UsedRange.columns.Count
For iLoop = 2 to Crow '---Read excel sheet row 從第row 2至最後row,就結束
Do '---當服務時&分=0 跳走不執行
'IF Range("'G'&iLoop").Value = 0 And Range("'H'&iLoop").Value = 0 Then
IF sheetB.Cells(iLoop,7).Value = 0 And sheetB.Cells(iLoop,8).Value = 0 Then
Exit Do
END IF
Select Case MID(sheetB.Range("B"&iLoop).Value, 2, 1) '---判斷男女,各別累計時數
Case "1"
MP_c = MP_c + 1
MH_c = MH_c + sheetB.Range("G"&iLoop).Value
Case "2"
FP_c = FP_c + 1
FH_c = FH_c + sheetB.Range("G"&iLoop).Value
End Select
'---分鐘數累計處理
IF sheetB.Range("H"&iLoop).Value = 0 then
elseIF sheetB.Range("H"&iLoop).Value = 30 then
CALL M2H_c(MID(sheetB.Range("B"&iLoop).Value, 2, 1)) '---利用sub參數,以判斷男女
else
Msgbox "服務分鐘is not 30 , row="&iLoop
WScript.Echo "excel檔未更新,需修改後,再執行! (need to amend not 30 minutes)"
wkBook.Close False ' 關閉 excel 檔案 (close wkBook file)
excelAPP.Quit ' 結束 EXCEL APP
WScript.Quit ' 發現錯誤資料,結束程式
End IF
Loop While False
Next
sheetR.Range("J2").Value = LEFT(sheetB.Range("C2").Value,5) '顯示本次處理月份
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,3).Value = MP_c '顯示row位置 = 月份+ 5
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,4).Value = FP_c
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,5).Value = MP_c + FP_c
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,6).Value = MH_c
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,7).Value = FH_c
sheetR.Cells(MID(sheetB.Range("C2").Value, 4, 2)+5,8).Value = MH_c + FH_c
'REM-----設定sheetR 為活動工作表
sheetR.Activate
wkBook.Save ' wkBook file rewrite;xlsx file need exist already
wkBook.Close False ' 必須 close wkBook file
excelAPP.Quit ' 離開 EXCEL APP
MsgBox "時數統計excel檔案更新並儲存完成 (sheets has been updated finished) "
Wscript.Quit ' 程式在此結束執行
'---Sub定義內容,依據男女,各別累計時數 +0.5
Sub M2H_c(MF_f)
IF MF_f = "2" then
FH_c = FH_c + 0.5
else
MH_c = MH_c + 0.5
End IF
End Sub
---by linct-----