2017-03-17 48 views
1

我有一個表(tbl_Composites),其中包含用於計算性能得分的公式。例如用相關值替換部分字符串公式

 KPI  |   FORMULA    | 
-------------------------------------------------- 
Productivity | [ItemsCompleted]/[LoggedInTime] | 
SalesConversion| [Sales]+[Leads]/[TotalCalls] | 

有一個擁有其中包含了每個人

SCOREDATE | USERID | METRIC  | VALUE | 
------------------------------------------------ 
01/03/2017 | 20511 | ItemsCompleted | 50 | 
01/03/2017 | 20511 | LoggedInTime | 320 | 
01/03/2017 | 20630 | Sales   | 8 | 
01/03/2017 | 20630 | Leads   | 3 | 
01/03/2017 | 20630 | TotalCalls  | 25 | 

我試圖寫一個VBA函數,將採取的參數,這些指標和相關值的列的另一個表(tbl_BaseData)日期,用戶ID和KPI,然後獲取該KPI公式的相關度量值並計算結果。

我有一些設法放在一起的東西,但效率不高,如果某個指標沒有記錄(例如有人接聽電話但沒有銷售),它就不起作用。

Function CalulateFormula(strFormula As String, userID As String, scoreDate As Date) As String 
Dim Metric As String, valueList As String 
Dim i As Integer 

For i = 1 To Len(strFormula) 
    If Mid(strFormula, i, 1) = "[" Then 
     Metric = Mid(strFormula, i + 1, InStr(i + 1, strFormula, "]") - i - 1) 
     valueList = valueList & "'" & Metric & "', " 
     CalulateFormula = CalulateFormula & Metric 
     i = InStr(i + 1, strFormula, "]") 
    Else 
     CalulateFormula = CalulateFormula & Mid(strFormula, i, 1) 
    End If 
Next i 

valueList = Left(valueList, Len(valueList) - 2) 

CalulateFormula = EvaluateSQL(CalulateFormula, valueList, userID, scoreDate) 

End Function 

這將構建公式字符串並填充它需要查找的度量標準列表。然後它調用另一個函數,如下所示,它運行一些SQL來獲取度量值並評估公式。

Function EvaluateSQL(CalulateFormula As String, valueList As String, userID  As String, scoreDate As Date) As String 
Dim strSQL As String 
Dim rs As DAO.Recordset 

    strSQL = "SELECT Metric, metricValue " & _ 
     "FROM tbl_BaseData " & _ 
     "WHERE metric in (" & valueList & ") AND userID = '" & userID & "' AND  scoreDate = #" & Format(scoreDate, "mm/dd/yyyy") & "# " 

Set rs = CurrentDb.OpenRecordset(strSQL) 

Do Until rs.EOF 
    CalulateFormula = Replace(CalulateFormula, rs!Metric, rs!metricValue) 
rs.MoveNext 
Loop 
EvaluateSQL = Eval(CalulateFormula) 
End Function 

這似乎是一個相當迂迴的做事方式,我想知道是否需要從完全不同的角度來處理問題。任何人都可以告訴我,如果有一個更簡單/更有效的方式,也將能夠處理空值/缺失值?

回答

2

它看起來像你在思考你的字符串代。您的FORMULA的值已經包含計算操作/,因此您可以讀取FORMULA的全部值作爲SQL計算。看起來您的很多擔心是使用FORMULA值中的括號,但SQL將讀取[ItemsCompleted]作爲計算的有效字段名稱。

比上述更好,你可以在SQL代碼中完全做到這一點。

這裏你真正需要的是每個用戶每天一行。有了它,您可以輕鬆運行您的指標;你甚至不需要tbl_Composites表。

因此,這裏是你怎麼做:

SELECT 
    SCOREDATE 
    ,USERID 
    ,ItemsCompleted/LoggedInTime as Productivity 
    ,Sales + Leads as SalesConversion 
    from 
    (SELECT distinct 
     base.SCOREDATE, 
     base.USERID, 
     ic.ItemsCompleted, 
     lt.LoggedInTime, 
     sls.Sales, 
     lds.Leads, 
     tc.TotalCalls 
    from (((((
    tbl_BaseData as base 
     left join 
      (SELECT SCOREDATE, USERID, VALUE as ItemsCompleted 
      from tbl_BaseData 
      where METRIC = 'ItemsCompleted') as ic 
      on base.USERID = ic.USERID 
       and base.SCOREDATE = ic.SCOREDATE) 
     left join 
      (SELECT SCOREDATE, USERID, VALUE as LoggedInTime 
      from tbl_BaseData 
      where METRIC = 'LoggedInTime') as lt 
      on base.USERID = lt.USERID 
       and base.SCOREDATE = lt.SCOREDATE) 
     left join 
      (SELECT SCOREDATE, USERID, VALUE as Sales 
      from tbl_BaseData 
      where METRIC = 'Sales') as sls 
      on base.USERID = sls.USERID 
       and base.SCOREDATE = sls.SCOREDATE) 
     left join 
      (SELECT SCOREDATE, USERID, VALUE as Leads 
      from tbl_BaseData 
      where METRIC = 'Leads') as lds 
      on base.USERID = lds.USERID 
       and base.SCOREDATE = lds.SCOREDATE) 
     left join 
      (SELECT SCOREDATE, USERID, VALUE as TotalCalls 
      from tbl_BaseData 
      where METRIC = 'TotalCalls') as tc 
      on base.USERID = tc.USERID 
       and base.SCOREDATE = tc.SCOREDATE)) 
     as p 

內部查詢做你的數據整合到每個用戶一行的工作,並考慮不存在的記錄類型。單獨返回:

SCOREDATE USERID ItemsCompleted LoggedInTime Sales Leads TotalCalls 
01/03/2017 20511 50    320   NULL NULL NULL 
01/03/2017 20630 NULL    NULL   8  3  25 

外部查詢然後計算生產率和銷售轉換。您可以爲需要的任何其他指標添加行。它返回:

SCOREDATE USERID Productivity SalesConversion 
01/03/2017 20511  0.156   NULL 
01/03/2017 20630  NULL   11 
+0

嗨Rominus。謝謝回覆。我不知道如何將公式直接輸入到SQL計算中,因爲公式的各個部分不是字段,它們是保存在[度量]字段中的值。你能舉個例子說明你的意思嗎?另外,我將公式的各個部分放在方括號內,以便我寫的函數能夠知道它們在哪裏開始和停止,但如果有更好的方法,我肯定會改變它。 – Leroy

+0

我越看越這個,我越覺得你的表結構是這種複雜性的根本原因。你提到你有問題,如果沒有特定類型的記錄;你能創建一個值爲零的記錄,而不是創建一條記錄嗎?無論如何,這對記錄保持更有意義,國際海事組織。 – Rominus

+0

好的,這完全在SQL中重複,它與不存在的記錄 – Rominus