[英]Replace parts of string formula with relevant values
我有一个表 ( tbl_Composites
),其中包含用于计算性能分数的公式。 例如
KPI | FORMULA |
--------------------------------------------------
Productivity | [ItemsCompleted]/[LoggedInTime] |
SalesConversion| [Sales]+[Leads]/[TotalCalls] |
还有另一个表 ( tbl_BaseData
),其中有一列包含这些指标和每个人的相关值
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 函数,该函数将采用日期、用户 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
这似乎是一种迂回的做事方式,我想知道我是否需要从一个完全不同的角度来解决这个问题。 任何人都可以告诉我是否有一种更简单/更有效的方法也可以处理空值/缺失值?
看起来您过度考虑了您的字符串生成。 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
然后外部查询计算 Productivity 和 SalesConversion。 您可以为您需要的任何其他指标添加行。 它返回:
SCOREDATE USERID Productivity SalesConversion
01/03/2017 20511 0.156 NULL
01/03/2017 20630 NULL 11
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.