標題:
[發問]
VBA使用 SQL 指令,User Defined Function(使用者自訂函數),如何輸入2個參數。
[打印本頁]
作者:
Baracuda
時間:
2012-1-28 15:47
標題:
VBA使用 SQL 指令,User Defined Function(使用者自訂函數),如何輸入2個參數。
參數內容 參數1:為欄位內容,參數2:為設定的常數
VBA 中設定引用 設定引用的是 Microsoft ActiveX Data Objects 2.0 Library
已經試過的內容 直接引用常數時可以 Work
=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(0.1)) + ')' as 勞退個人 " & _
指定參數(宣告為常數)不Work
Const Labor_Pension_Personal_rate = 0.1
=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(Labor_Pension_Personal_rate)) + ')' as 勞退個人 " & _
錯誤訊息:參數太少,預期個數1
參考內容 Excel 巨集魔法書 李潛瑞著 page99
問題背景 想要在 Excel VBA中使用SQL來計算勞健保及勞退的個人負擔金額
lcCommandText = "SELECT 序號, 姓名, 核定本薪, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(Labor_Pension_Personal_rate)) + ')' as 勞退個人 " & _
作者:
Baracuda
時間:
2012-1-28 15:49
標題:
輸入2個參數 Source Code。
Option Explicit
Option Base 0
Sub main()
Call SQL_Insurance_Burden
End Sub
Function Multiply_2_No_Round_Down_4_Up_5(Number1 As Single, Number2 As Single) As Long
' 目的
' 2數相乘再做4捨5入
Multiply_2_No_Round_Down_4_Up_5 = Int(Number1 * Number2 + 0.5)
End Function
Sub SQL_Insurance_Burden()
Const Output_Sht = "輸出表"
Const Input_Sht = "輸出表"
Const Labor_Pension_Personal_rate = 0.1
Dim lcConnectionString As String
Dim lcConnectString, lcCommandText As String
Dim loADODBConnection As ADODB.Connection
Dim loADODBRecordset As ADODB.Recordset
lcConnectionString = "Driver={Microsoft Excel Driver (*.xls)}; " & _
"DBQ=" + ActiveWorkbook.FullName + ";" & _
"ReadOnly=True"
lcCommandText = "SELECT 序號, 姓名, 核定本薪, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(Labor_Pension_Personal_rate)) + ')' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
' Work
'1 " '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(0.1)) + ')' as 勞退個人 " & _
' 不 Work
'1 " '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(Labor_Pension_Personal_rate)) + ')' as 勞退個人 " & _
'2 " '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + Labor_Pension_Personal_rate + ')' as 勞退個人 " & _
Set loADODBConnection = CreateObject("ADODB.Connection")
Set loADODBRecordset = CreateObject("ADODB.Recordset")
Debug.Print lcCommandText
loADODBConnection.Open lcConnectionString
loADODBRecordset.Open lcCommandText, loADODBConnection, 3, 1, 1
Sheets(Output_Sht).Select
Dim r, f As Integer
r = 1
For f = 0 To loADODBRecordset.Fields.Count - 1
Sheets(Output_Sht).Cells(r, f + 1) = loADODBRecordset.Fields(f).Name
Next
While Not loADODBRecordset.EOF
r = r + 1
For f = 0 To loADODBRecordset.Fields.Count - 1
Sheets(Output_Sht).Cells(r, f + 1) = loADODBRecordset.Fields(f).Value
Next
loADODBRecordset.MoveNext
Wend
End Sub
複製代碼
作者:
kimbal
時間:
2012-1-31 13:54
Baracuda 發表於 2012-1-28 15:49
試試把sql換成這個樣子
lcCommandText = "SELECT 序號, 姓名, 核定本薪, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + 勞退 + '," + Trim(Str(Labor_Pension_Personal_rate)) + ")' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
複製代碼
作者:
Baracuda
時間:
2012-2-2 12:30
Error Message 參數太少,預期個數1
還是有問題。
我尚不知如何解。
可能用 SQL 查出後再另用 VBA 寫過。
作者:
Hsieh
時間:
2012-2-2 14:04
回復
4#
Baracuda
你的意思不是要將字串中的常數用變數取代嗎?
lcCommandText = "SELECT 序號, 姓名, 核定本薪, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(" & Labor_Pension_Personal_rate & ")) + ')' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
作者:
Baracuda
時間:
2012-2-4 08:41
是的,版主我試看看。
作者:
Baracuda
時間:
2012-2-4 08:44
Hsieh 版主:
我的意思不是要將字串中的常數用變數取代嗎。
但是語法好像只能用欄位。
如果VBA 中設定的變數(or常數)會有問題。
作者:
Scott090
時間:
2015-9-24 09:15
回復
7#
Baracuda
純屬討論及個人看法
VBA ADO SQL 好像並不支援變數運算,
UDF也只是在結果欄位放入計算式而不是ADO會直接計算
這個題目,個人的看法是ADO的支援能力問題而不是 UDF 裡有幾個參數
主欄位也一樣不能用變數計算:
隨意舉例 "核定本薪"
Const aa=2
可以計算; 核定本薪 * 直接常數 2
lcCommandText = "SELECT 序號, 姓名, 核定本薪 * 2 as bb, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(0.1)) + ')' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
可以計算; 核定本薪 * " & aa & " ,變數已在成立 lcCommandText 字串時轉化了 aa 為 2,2 是常數不是變數
lcCommandText = "SELECT 序號, 姓名, 核定本薪 * " & aa & " as bb, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(0.1)) + ')' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
不會計算; 核定本薪 * aa 的變數 aa 是 lcCommandText 字串的一部分, ADO沒支援字串內的變數
lcCommandText = "SELECT 序號, 姓名, 核定本薪 * aa as bb, 核定績效 , 薪資總額 , 勞保薪資 , 勞退薪資 , 健保薪資, " & _
" 勞退 , 職災, 普通事故, 就業保險, 工資墊償, 全民健保, 全民健保舊, " & _
" '=Multiply_2_No_Round_Down_4_Up_5(' + trim(str(勞退)) + ',' + trim(str(0.1)) + ')' as 勞退個人 " & _
"FROM " & "[" & Input_Sht & "$" & "A1:P32]"
作者:
Scott090
時間:
2015-9-24 10:22
回復
7#
Baracuda
假設,
1. Excel VBA ADOSQL 並不支援 變數
2. SQL只是可以技巧性的在生成的欄位放入計算式,此計算式可以演算原始欄位資料
那就在 Excel 儲存格 放入計算式來呼叫 VBA內的 UDF,
此自訂函數就較有寬廣的運作空間了
歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)